问题描述:
public class A{StatusDAO statusDAO;
FooDAO fooDAO;
BarDAO barDAO:
Long id = 111111;public void exec(){
int status = statusDAO.getStatus(id);
if(status > ){
//在数据库的foo表中插入一条记录
long id = fooDAO.insert(id);
//在数据库的bar表中删除一条记录
barDAO.delete(id);
}
......
}}现在问题是,
1.怎样保证
long id = fooDAO.insert(id);
barDAO.delete(id);
这两句的原子性。即这两个操作要么都执行,要么都不执行()。
2.还要考虑多线程对status的读取存在的安全问题我知道用事务可以解决原子性问题,但我现在的环境里,人工无法干预事务,即得不到Transaction的上下文。
public class A{StatusDAO statusDAO;
FooDAO fooDAO;
BarDAO barDAO:
Long id = 111111;public void exec(){
int status = statusDAO.getStatus(id);
if(status > ){
//在数据库的foo表中插入一条记录
long id = fooDAO.insert(id);
//在数据库的bar表中删除一条记录
barDAO.delete(id);
}
......
}}现在问题是,
1.怎样保证
long id = fooDAO.insert(id);
barDAO.delete(id);
这两句的原子性。即这两个操作要么都执行,要么都不执行()。
2.还要考虑多线程对status的读取存在的安全问题我知道用事务可以解决原子性问题,但我现在的环境里,人工无法干预事务,即得不到Transaction的上下文。
barDAO.delete(id);
这两句是同一个事务吗?我想应该不是吧,在你DAO的程序里肯定是一个方法一个事务
这两个方法不会干扰对方吧
在调用delete方法之前insert方法一定是执行完了的,insert方法的事务也commit了
怎么可能得不到?不大可能吧。
事务要不是你亲自管理的,即你用代码来控制开启事务,提交事务,提交事务的时机。
要不你的事务就是通过Spring这种框架来用切面进行管理的。看你用dao方法的返回值来表示数据库操作的成败,我判断你可能是个新手。
(如果说错了,望楼主海涵。)
那不妨把这个问题先放一放,等熟悉了Spring和jdbc以后再说。要不你这个程序的结构改一改。
在exec方法里面得到一个 Connection; 关闭自动提交;然后再把Connection传给fooDao,barDao
等fooDao.insert() 和 barDao.delete() 两个方法都结束以后,判断两个个方法的返回值。都成功了则
提交。 其中之一失败了,回滚。
import java.sql.Connection;
import java.sql.DriverManager;public final class DBHelper {
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); public static synchronized Connection getConnection() throws Exception {
Connection conn = tl.get();
if (conn == null) {
String username = "****";
String password = "****";
String url = "**************************";
Class.forName("****");
conn = DriverManager.getConnection(url, username, password);
conn.setAutoCommit(false);
tl.set(conn);
}
return conn;
}
public static void commit() throws Exception {
getConnection().commit();
}
public static void rollback() throws Exception {
getConnection().rollback();
}
}
一个工具类,希望对你有帮助。
public void exec(){
int status = statusDAO.getStatus(id);
if(status > 0){
//把status置为0
statusDAO.setStatus(0);
//在数据库的foo表中插入一条记录
long id = fooDAO.insert(id);
//在数据库的bar表中删除一条记录
barDAO.delete(id);
}
......
}
同时被两个线程ThreadA,ThreadB访问,
当ThreadA执行到if(status > 0)时,被阻塞,然后ThreadB执行到if(status > 0)。这样ThreadA,ThreadB都会因status > 0而继续执行{}内的代码。
而且这个类被放在多台服务器组成的集群上。
2) 如果抛出已检查异常,事务立即提交。这种东西设计成这样到底有什么好处,不是一两句话可以说清楚的。我看来,你的程序结构就是有严重问题的。
如楼上的几位朋友说的,事务的管理不应该在dao层,而是在service层的。
但是从你的代码看,很难看清你的代码在什么层次上,有点不伦不类的。