Java 使用SpringJDBC轻松完成事务?
我正在开发一个使用Spring和JDBC模板类的Java应用程序。我有一个DAO类,它有4个方法:m1()到m4()。m1在表t1上执行多次插入和更新,m2在表t2上执行多次插入和更新,m3在表t3上执行多次插入和更新,等等 DAO方法使用如下:Java 使用SpringJDBC轻松完成事务?,java,spring,jdbc,transactions,rollback,Java,Spring,Jdbc,Transactions,Rollback,我正在开发一个使用Spring和JDBC模板类的Java应用程序。我有一个DAO类,它有4个方法:m1()到m4()。m1在表t1上执行多次插入和更新,m2在表t2上执行多次插入和更新,m3在表t3上执行多次插入和更新,等等 DAO方法使用如下: while(true) { //process & generate data dao.m1(data1); dao.m2(data2); dao.m3(data3); dao.m4(data4); //sleep
while(true)
{
//process & generate data
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
//sleep
}
我希望在4个连续方法调用下的db操作是原子的,要么所有4个表都成功更新,要么没有更新。因此,如果在m3()中执行操作时出错,我想回滚在m2和m1中执行的所有更改(更新和插入)
那么spring是否允许您按照以下方式进行操作
while (true)
{
//process & generate data
transaction = TransactionManager.createNewTransaction();
transaction.start()
try
{
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
catch(DbUpdateException e)
{
transaction.rollBack();
}
transaction.end();
// sleep
}
或者有更好的方法吗?是的,您可以将这些调用放在方法中并指定您的事务 您不需要添加代码,Spring可以为您完成 是的,Spring允许您这样做 我个人更喜欢使用注释,如下所示:
public void runBatchJob() {
while (true) {
// generate work
doWork(unitOfWork);
}
}
@Transactional
private void doWork(UnitOfWork work) {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
}
定义DAO函数时:
@Transactional
public void m1(Data data) {
...
}
这需要在applicationContext.xml中:
声明性事务可以声明为需要事务、需要新事务、支持事务等。当使用
@Transactional
注释的块抛出运行时异常时,将发生回滚。为完整起见,编程解决方案将是:
private TransactionTemplate transactionTemplate;
public setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
...
while (true) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
} catch(DbUpdateException e) {
status.setRollbackOnly();
}
}
});
}
Spring可以通过使用@Transactional(如所述)或XML(如果您愿意)来处理这一切
正确的导入方法是您想要的事务传播类型,这一切都取决于您的应用程序
默认情况下,如果一个事务不存在,则将启动该事务;如果一个事务已经启动,则将重新使用现有事务。如果希望所有4个DAO都是原子的,那么这就是您想要的行为
将@Transactional放在一个类上,该类将管理名为(MyService)的DAO方法——该层下的任何内容现在都将参与该事务边界
i、 e:
在代码中这样做完全没有必要
请参见我认为不需要将m1、m2等注释为@Transactional。如果任何人抛出异常,doWork已经完成的所有内容都将回滚。您不需要在此上下文中这样做,不需要。但是如果他们正在进行更新,您应该将其注释为需要事务,否则如果您在doWork()之外调用它们,您可能会发现自己正在进行非事务性更新当@Transactional注释应用于私有方法时,它有什么作用吗?是的,私有已不像以前那样私有了。:)
@Transactional
public void m1(Data data) {
...
}
@Transactional
public void m2(Data data) {
...
}