解决erlang和java同时操作一张表,造成锁表问题
2015-01-22 23:58
393 查看
作者:张昌昌
1、问题描述
Erlang端通过odbc去写oracle一张表,同时java通过jdbc驱动也去写这张表,当同时多次发生这种写操作时,这个表就被锁。
2、问题解决
思路:利用适配器原理,适配erlang和java的数据库连接,让erlang端对数据表的操作与java端对该数据表的操作,分时序顺序进行,其中一端在进行写操作时上锁
另一端就不能操作,直到他操作完成释放锁,另一端才能操作。
该适配器采用java编写,通过otp.jar让erlang与java进行通信,erlang和java对数据表操作的连接都要从该适配器入
实现方式:
(1)java端
public class ConnectionAdaptor {
private static final ConnectionAdaptor instance = new ConnectionAdaptor("javaNode","theMailbox","secret");
private OtpNode node;
private static OtpMbox mbox;
private ReentrantLock lock = new ReentrantLock();
public static ConnectionAdaptor getInstance(){
return instance;
}
private ConnectionAdaptor(String nodeName,String mboxName,String cookie){
super();
try{
node=new OtpNode(nodeName,cookie);
}catch(IOException e){
e.printStackTrace();
}
System.out.print(node);
mbox = node.createMbox(mboxName);
}
private void process(){
while(true){
try{
OtpErlangObject msg = mbox.receive();
OtpErlangTuple t = (OtpErlangTuple)msg;
OtpErlangPid from = (OtpErlangPid)t.elementAt(0);
String name = ((OtpErlangString)t.elementAt(1)).stringValue();
if(name.equals("write_start"))
adaptor(1);
}catch(Exception e){
}
}
}
public static void main(String[] args){
//启动一个线程用于erlang消息的侦听
new Thread(){
public void run(){
ConnectionAdaptor.getInstance().process();
}
}.start();
//启动一个线程进行java端的数据表操作
new Thread(){
public void run()
{
for(int i=0;i<10;i++)
{
try{
try{
ConnectionAdaptor.getInstance().adaptor(2);
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}.start();
}
public void adaptor(int type){
lock.lock();
if (type == 1)
{
while(true)
{
OtpErlangObject msg = mbox.receive();
OtpErlangTuple t = (OtpErlangTuple)msg;
OtpErlangPid from = ((OtpErlangString)t.elementAt(1)).stringValue();
if(name.equals("write_end"))
{
System.out.println("erlang write table end");
lock.unlock();
}
}
}
else
{
Thread.sleep(5000);
System.out.println("java write table end");
lock.unlock();
}
}
}
erlang端:
-module(erl_to_java).
-export([write_table/0,start/1]).
write_table() ->
{theMailbox,javaNode@zcc}!{self(),"write_start"},
timer:sleep(5000),
{theMailbox,javaNode@zcc}!{self(),"write_end"}.
start(N) ->
case N =:= 0 of
true -> ok;
false -> write_table(),start(N-1)
end.
3、时序图
4、问题总结
(1)java单例模式
(2)java与erlang通信
(3)java线程间锁机制
首先利用单例模式获取一个适配器对象,然后启动一个线程执行process(),侦听来自erlang端的写表消息,一旦有erlang发出写表请求,需加锁,在erlang进程中执行
写表操作后,向java进程发送写表结束请求,然后java进程释放锁,一旦有java端写表操作,便获取锁进行写表操作,之后释放锁,在java写表期间,erlang的写表操作必须等待,直到锁释放,反之亦然。
5、使用方法
(1)运行该适配器的java端需要安装erl的运行环境,需要导入OtpErlang.jar包;
(2)erlang端节点启动时,要和适配器单例创建时的cookie保持一致,同时
erl -sname erlangNode -setcookie secret -pa "erl_to_java.bin所在的路径" -eval "net_adm:ping(javaNode@zcc)"
1、问题描述
Erlang端通过odbc去写oracle一张表,同时java通过jdbc驱动也去写这张表,当同时多次发生这种写操作时,这个表就被锁。
2、问题解决
思路:利用适配器原理,适配erlang和java的数据库连接,让erlang端对数据表的操作与java端对该数据表的操作,分时序顺序进行,其中一端在进行写操作时上锁
另一端就不能操作,直到他操作完成释放锁,另一端才能操作。
该适配器采用java编写,通过otp.jar让erlang与java进行通信,erlang和java对数据表操作的连接都要从该适配器入
实现方式:
(1)java端
public class ConnectionAdaptor {
private static final ConnectionAdaptor instance = new ConnectionAdaptor("javaNode","theMailbox","secret");
private OtpNode node;
private static OtpMbox mbox;
private ReentrantLock lock = new ReentrantLock();
public static ConnectionAdaptor getInstance(){
return instance;
}
private ConnectionAdaptor(String nodeName,String mboxName,String cookie){
super();
try{
node=new OtpNode(nodeName,cookie);
}catch(IOException e){
e.printStackTrace();
}
System.out.print(node);
mbox = node.createMbox(mboxName);
}
private void process(){
while(true){
try{
OtpErlangObject msg = mbox.receive();
OtpErlangTuple t = (OtpErlangTuple)msg;
OtpErlangPid from = (OtpErlangPid)t.elementAt(0);
String name = ((OtpErlangString)t.elementAt(1)).stringValue();
if(name.equals("write_start"))
adaptor(1);
}catch(Exception e){
}
}
}
public static void main(String[] args){
//启动一个线程用于erlang消息的侦听
new Thread(){
public void run(){
ConnectionAdaptor.getInstance().process();
}
}.start();
//启动一个线程进行java端的数据表操作
new Thread(){
public void run()
{
for(int i=0;i<10;i++)
{
try{
try{
ConnectionAdaptor.getInstance().adaptor(2);
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}.start();
}
public void adaptor(int type){
lock.lock();
if (type == 1)
{
while(true)
{
OtpErlangObject msg = mbox.receive();
OtpErlangTuple t = (OtpErlangTuple)msg;
OtpErlangPid from = ((OtpErlangString)t.elementAt(1)).stringValue();
if(name.equals("write_end"))
{
System.out.println("erlang write table end");
lock.unlock();
}
}
}
else
{
Thread.sleep(5000);
System.out.println("java write table end");
lock.unlock();
}
}
}
erlang端:
-module(erl_to_java).
-export([write_table/0,start/1]).
write_table() ->
{theMailbox,javaNode@zcc}!{self(),"write_start"},
timer:sleep(5000),
{theMailbox,javaNode@zcc}!{self(),"write_end"}.
start(N) ->
case N =:= 0 of
true -> ok;
false -> write_table(),start(N-1)
end.
3、时序图
4、问题总结
(1)java单例模式
(2)java与erlang通信
(3)java线程间锁机制
首先利用单例模式获取一个适配器对象,然后启动一个线程执行process(),侦听来自erlang端的写表消息,一旦有erlang发出写表请求,需加锁,在erlang进程中执行
写表操作后,向java进程发送写表结束请求,然后java进程释放锁,一旦有java端写表操作,便获取锁进行写表操作,之后释放锁,在java写表期间,erlang的写表操作必须等待,直到锁释放,反之亦然。
5、使用方法
(1)运行该适配器的java端需要安装erl的运行环境,需要导入OtpErlang.jar包;
(2)erlang端节点启动时,要和适配器单例创建时的cookie保持一致,同时
erl -sname erlangNode -setcookie secret -pa "erl_to_java.bin所在的路径" -eval "net_adm:ping(javaNode@zcc)"
相关文章推荐
- 多台应用同时操作一张表数据,解决并发问题
- 解决系统间互通问题的同时也会造成IT黑洞
- MS CRM异步操作造成的问题以及解决方法
- 解决java和.NET互相操作memcache差异问题
- MySQL SELECT同时UPDATE同一张表问题发生及解决
- Java中String类(字符串操作)的10个常见问题和解决方法
- [转]在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
- 触发器(当2个表中的相应值改变时同时改变一个表中的一个字段)(同时有处理“无法解决 equal to 操作的排序规则冲突”问题)
- (转)javabean操作文件正确,但是Jsp调用javabean时文件路径出错问题解决之JavaBean访问本地文件实现路径无关实现方法
- 在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
- Fragment内部控件操作的E/AndroidRuntime(1778): java.lang.NullPointerException问题解决
- Java 编程技术中汉字问题的分析及解决,文件操作
- 解决java和.NET互相操作memcache差异问题
- MySQL SELECT同时UPDATE同一张表问题发生及解决
- Java中按照行读取和写入文件 日志常用操作 解决中文乱码问题
- Java 编程技术中汉字问题的分析及解决,文件操作
- Java 编程技术中汉字问题的分析及解决,文件操作
- 同时安装了Windwos与LinuxOS 或 磁盘分区误操作等引起两个系统都无法启动问题的解决
- Knockout与Require框架同时使用时的visible绑定的问题,造成的影响,以及解决的方法。
- [JAVA]Apache FTPClient操作“卡死”问题的分析和解决