我使用spring的事务,用aop完成事务配置管理。
businessObject
method
transaction begin start
invoke DataAccessObject1.method
invoke DataAccessObject2.method
transaction commit
为什么让DAO的方法循环依赖,自找麻烦阿。
发表人: SportsBaby1980 发表文章: 244 / 注册时间: 2004-06
Dao只能使用资源,而不应该管理资源。
也就是说,Dao可以使用Connection,但不能维护它----生成和关闭。
发表人: SportsBaby1980 发表文章: 244 / 注册时间: 2004-06
我认为事务不要有dao来处理。
应该由业务方法处理
发表人: zdbj2ee 发表文章: 16 / 注册时间: 2003-08
dao代码中不应有事务处理存在,应在调用dao的业务方法中调用。
我使用spring的事务,用aop完成事务配置管理。
businessObject
method
transaction begin start
invoke DataAccessObject1.method
invoke DataAccessObject2.method
transaction commit
发表人: yanchaomin 发表文章: 1 / 注册时间: 2005-06
为什么不用ThreadLocal进行connection的处理呢?这样即使有多个类的方法放在一起运行,也只是使用一个connection,并且可以使用事务。
本人认为 SportsBaby1980 说的是对的。将DAO单独分出来的目的是把业务处理部分和数据库访问部分相分离。而我们应用程序中的事务,我认为属于业务逻辑的一部分。
正如 zdbj2ee 所说: "dao代码中不应有事务处理存在,应在调用dao的业务方法中调用。"
yanchaomin 的建议不错,实际上我们的项目也是这样做的(请问你是用LEO架构的吗?),解决事务问题,这是个不错的方法。
下面发个我们现在的做法给大家参考,多提意见(这种做法有好有坏,大家一起来想想如何改进)!
public class BasicDAO
{
String _driver;
String _url;
String _user;
String _password;
String _datasource;
DataSource _ds;
static ThreadLocal _session = new ThreadLocal();
public BasicDAO(String datasource)
throws Exception
{
_datasource = datasource;
Context ctx = null;
try
{
ctx = JNDIUtil.getDefaultContext();
_ds = (DataSource)ctx.lookup(datasource);
}
catch(Exception e)
{
ctx = SysConfig.getZHContext();
_ds = (DataSource)ctx.lookup(datasource);
}
}
public void begin()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx != null)
{
throw new Exception("Already in a tranction.");
} else
{
ctx = new TransactionContext();
_session.set(ctx);
return;
}
}
public void commit()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx == null)
throw new Exception("No in an transaction.");
ctx.commit();
_session.set(null);
break MISSING_BLOCK_LABEL_48;
Exception exception;
exception;
_session.set(null);
throw exception;
}
public void rollback()
throws Exception
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx == null)
throw new Exception("No in an transaction.");
ctx.rollback();
_session.set(null);
break MISSING_BLOCK_LABEL_48;
Exception exception;
exception;
_session.set(null);
throw exception;
}
public Connection getConnection()
throws Exception
{
if(_ds != null)
{
TransactionContext ctx = (TransactionContext)_session.get();
if(ctx != null)
{
Connection conn = ctx.getConnection();
if(conn == null)
{
Connection conn1 = _ds.getConnection();
conn1.setAutoCommit(false);
conn = new ConnectionWrapper(conn1);
ctx.setConnection(conn);
}
return conn;
} else
{
return _ds.getConnection();
}
} else
{
return DriverManager.getConnection(_url, _user, _password);
}
}
public int executeUpdate(String sql)
throws Exception
{
Connection conn;
Statement stmt;
conn = null;
stmt = null;
int i;
SQLException e;
int code;
byte byte0;
try
{
conn = getConnection();
if(logger.isDebugEnabled())
logger.debug(sql);
stmt = conn.createStatement(1005, 1008);
i = stmt.executeUpdate(sql);
}
finally
{
try
{
if(stmt != null)
stmt.close();
}
catch(Exception e) { }
try
{
if(conn != null)
conn.close();
}
catch(Exception e) { }
}
return i;
e;
code = e.getErrorCode();
logger.error("SQLException", e);
if(code == 1)
ErrorHandle.throwError("999001", 0, "BasicDAO");
else
ErrorHandle.throwError("999002", 0, "BasicDAO");
byte0 = -1;
return byte0;
}
我现在的系统也是写存储过程的(不是我写),而且报表生成也是依赖存储过程的,方便是方面,但是感觉有点不对尽,但我又说不出来 ,哪里可能出现问题,我指系统维护等方面....
实际在connection 上加了互斥锁,但是考虑不全面.
如果在并发情况下,有对methodA()和methodB()同时访问,效率会很大降低.
1.用threadlocal处理connection---可以。但是不好,可能会很糟
a.不好。如果存在一种情况。一个web app需要2个库的数据。你需要在设置2个threadlocal。而且(使用struts)需要重载baseaction中的execute方法,每次都要setCurrent(我当初遇到的问题是在logon时设置后,如果不每次设置,有的时候得不到。)
b.很糟。如果调用service的线程和service不是一个线程......
2.antzl->除了使用dao,可以使用hibernate。---可以。但是不好,如果您这么使用Hibernate,拿不是您在使用他,而是您在依赖他。您可能需要和他解耦了.....
我认为,dao是一种设计思想。hibernate我更情愿认为他只是一种实现手段而已(甚至,如果使用他,我只是拿他当作daoImp的一种方式。虽然hibernate自己可以进行事务管理等等DAOManager的功能)。
3.使用存储过程--可以。但是不太好。如果简单的系统。表不超过5个。我宁愿使用存储过程。原因很简单--开发快!但是如果项目大,谁来天天清醒的维护那些存储过程呢(当然还有开发人员需要清醒的知道那些sp是给他用的)?
我的解决办法(由于水平问题。我还没深入的学习什么是ioc和aop):
类似于antzl 前面指出的“我一般用IOC解决类似问题,请大家讨论优缺点”的方法。有daomanager来管理transaction。
我不太喜欢用hibernate。因为他的效率不是很好。我们现在的项目,一个transaction需要batch操作大概5000记录。如果用hibernate我就需要等好久啊。所以我更喜欢用jdbc一些
以上只是小弟的一点想法。由于经验和水平的限制。还请各位大哥大姐多多指点。