是否有人在查询erlang时遇到此错误:
{:错误,:process_not_owner_of_odbc_connection}
我正在编写一个连接池,:ODBC.connect('conn )在genserver中运行,返回的pid被放入状态.但是当我将这个PID从gen服务器返回时,当我尝试使用这个pid运行一个:odbc.param_query时,我们应该如何创建一个连接池,如果我们可以使用在一个genserver中创建的pids呢?
有人有什么想法吗?
GenServer:
defmodule ItemonboardingApi.ConnectionPoolWorker do
use GenServer
def start_link([]) do
IO.puts "Starting Connection Pool"
GenServer.start_link(__MODULE__, nil, [])
end
def init(_) do
:odbc.start
{ok, pid} = :odbc.connect('DSN=;UID=;PWD=', [])
IO.inspect pid
{:ok, pid}
end
def handle_call(:get_connection, _from, state) do
IO.puts "Inspecting State:"
IO.inspect state
IO.puts("process #{inspect(self())} getting odbc connection")
{:reply, state, state}
end
end呼叫功能:
def get_standards_like(standard) do
:poolboy.transaction(
:connection_pool,
fn pid ->
connection = GenServer.call(pid, :get_connection)
IO.inspect connection
val =
String.upcase(standard)
|> to_char_list
# Call Stored Proc Statement
spstmt = '{call invlibr.usp_vm_getStandards (?)}'
case :odbc.param_query(connection, spstmt, [
{{:sql_char, 50}, [val]}
])
|> map_to_type(ItemonboardingCore.Standard)
do
{:ok, mapped} ->
{:ok, mapped}
{:updated, affected_count} ->
{:ok, affected_count}
{:executed, o, a} ->
{:ok, o, a}
{:error, _} ->
{:bad}
end
end
)
end我已经确认genserver中的pids感染了正确的odbc,并且GenServer.Call返回其中一个。
*编辑*这里是我为解决这个问题所做的工作。我不知道创建连接的进程必须是运行查询的进程。将查询传递给我的工作人员进行了轻微的更改,解决了我的问题。这是一个粗略的第一关,一些事情仍然需要做的工人。
defmodule ItemonboardingApi.ConnectionPoolWorker do
use GenServer
def start_link([]) do
IO.puts "Starting Connection Pool"
GenServer.start_link(__MODULE__, nil, [])
end
def init(_) do
:odbc.start(:app)
{ok, pid} = :odbc.connect('DSN=;UID=;PWD=', [])
IO.inspect pid
{:ok, pid}
end
def handle_call(:get_connection, _from, state) do
{:reply, state, state}
end
def handle_call({:query, %{statement: statement, params: params}}, _from, state) do
#TODO Check if pid is alive and start if needed.
{:reply, :odbc.param_query(state, to_charlist(statement), params), state}
end
end发布于 2018-03-05 23:09:14
这将是一个问题,正如Kevin指出的那样,不能为odbc和其他驱动程序(如mysql/otp )传递连接所有权。
如果您想使用连接池,请看一下下面的https://github.com/mysql-otp/mysql-otp-poolboy
否则,您可以使用任何池,但执行sql查询的进程必须是打开连接的进程。
Erlang实例
sql_query_priv(Conn, Conn_Params, {SQL, Params}) ->
lager:debug("~p:sql_query_priv trying to execute query: ~p, with params: ~p, conn = ~p~n", [?MODULE, SQL, Params, Conn]),
case Conn of
null -> try mysql:start_link(Conn_Params) of
{ok, NewConn} ->
lager:info("~p:sql_query_priv Connection to DB Restored", [?MODULE]),
try mysql:query(NewConn, SQL, Params) of
ok -> {ok, NewConn, []};
{ok, _Columns, Results} -> {ok, NewConn, Results};
{error, Reason} ->
lager:error("~p:sql_query_priv Connection To DB Failed, Reason: ~p~n", [?MODULE, {error, Reason}]),
exit(NewConn, normal),
{error, null, Reason}
catch
Exception:Reason ->
lager:error("~p:sql_query_priv Connection To DB Failed, Exception:~p Reason: ~p~n", [?MODULE, Exception, Reason]),
{error, null, {Exception, Reason}}
end;
{error, Reason} ->
lager:error("~p:sql_query_priv Connection To DB Failed, Reason: ~p~n", [?MODULE, {error, Reason}]),
{error, Conn, Reason}
catch
Exception:Reason ->
lager:error("~p:sql_query_priv Connection To DB Failed, Exception:~p Reason: ~p~n", [?MODULE, Exception, Reason]),
{error, Conn, {Exception, Reason}}
end;
Conn -> try mysql:query(Conn, SQL, Params) of
ok -> {ok, Conn, []};
{ok, _Columns, Results} -> {ok, Conn, Results};
{error, Reason} ->
try exit(Conn, normal) of
_Any -> ok
catch
_E:_R -> ok
end,
lager:error("~p:sql_query_priv Connection To DB Failed, Reason: ~p~n", [?MODULE, {error, Reason}]),
{error, null, Reason}
catch
Exception:Reason ->
try exit(Conn, normal) of
_Any -> ok
catch
_E:_R -> ok
end,
lager:error("~p:sql_query_priv Connection To DB Failed, Exception:~p Reason: ~p~n", [?MODULE, Exception, Reason]),
{error, null, {Exception, Reason}}
end
end. 发布于 2018-03-05 21:54:31
根据相关文件,odbc连接对于创建连接的Genserver进程是私有的。
打开到数据库的连接。连接与创建它的进程相关联,并且只能通过它访问。此函数可能会产生新的进程来处理连接。如果创建连接的进程死亡,或者调用disconnect/1,这些进程将终止。
您可以将其与可以设置为ETS的private表进行比较,但在ETS表的情况下,您可以将它们设置为public。这在odbc连接中是不可能的,因此您应该将代码移动到Genserver中。
https://stackoverflow.com/questions/49117365
复制相似问题