java 使用 Spring JDBC 的简单事务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1023907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Easy transactions using Spring JDBC?
提问by letronje
I am working on a Java app that uses Spring IoCand JDBC Template classes. I have a DAO class that has 4 methods : m1() to m4(). m1 performs multiple inserts and updates on table t1, m2 on table t2, m3 on t3, etc.
我正在开发一个使用 Spring IoC和 JDBC 模板类的 Java 应用程序。我有一个 DAO 类,它有 4 个方法:m1() 到 m4()。m1 在表 t1 上执行多次插入和更新,在表 t2 上执行 m2,在 t3 上执行 m3,等等。
The DAO methods are used as follows:
DAO 方法的使用如下:
while(true)
{
//process & generate data
dao.m1(data1);
dao.m2(data2);
dao.m3(data3);
dao.m4(data4);
//sleep
}
I want the db operations under the 4 consecutive method calls to be atomic, either all the 4 tables are updated successfully or none are. So, if there is an error while performing operations in m3(), i want to rollback all the changes(updates & inserts) performed in m2 & m1.
我希望 4 个连续方法调用下的 db 操作是原子的,要么所有 4 个表都更新成功,要么都不更新。因此,如果在 m3() 中执行操作时出现错误,我想回滚在 m2 和 m1 中执行的所有更改(更新和插入)。
So does spring let you do it the following way ?
那么 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
}
}
or are there better ways to do it?
或者有更好的方法吗?
采纳答案by Maarten Winkels
For completeness, the programmatic solution would be:
为完整起见,程序化解决方案将是:
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();
}
}
});
}
回答by cletus
Yes Spring allows you to programmatically control transactions.
是的 Spring 允许您以编程方式控制事务。
Personally I prefer declarative transactionsusing annotations, which goes like this:
我个人更喜欢使用注释的声明式事务,它是这样的:
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);
}
where the DAO functions are defined:
其中定义了 DAO 函数:
@Transactional
public void m1(Data data) {
...
}
This requires in your applicationContext.xml:
这需要在您的applicationContext.xml 中:
<tx:annotation-driven/>
Declarative transactions can be declared to require a transaction, require a new transaction, support transactions, etc. Rollback will occur when a block annotated with @Transactionalthrows a RuntimeException.
声明性事务可以声明为需要一个事务、需要一个新事务、支持事务等。当一个用@Transactionalthrows注释的块时会发生回滚RuntimeException。
回答by JARC
Spring can handle this all for you by using @Transactional as explained or in XML if you'd prefer.
如果您愿意,Spring 可以按照说明使用 @Transactional 或在 XML 中为您处理这一切。
The import thing to get right is the type of Transaction Propagationyou want which all depends on your application.
正确的导入是您想要的事务传播类型, 这一切都取决于您的应用程序。
By default a transaction will be started if one doesn't exist, and will re-use an existing transaction if one has already been started. This is the behavior you want if you want all 4 DAOs to be atomic.
默认情况下,如果一个事务不存在,则将启动该事务,如果一个事务已经启动,则将重新使用现有事务。如果您希望所有 4 个 DAO 都是原子的,这就是您想要的行为。
Put @Transactional on a class which will manage the DAO methods called (MyService) - anything below this layer will now take part in that transaction boundary.
将@Transactional 放在一个类上,该类将管理名为 (MyService) 的 DAO 方法 - 此层以下的任何内容现在都将参与该事务边界。
i.e:
IE:
@Transactional
public void m1(Data data) {
...
}
@Transactional
public void m2(Data data) {
...
}
Doing this in code is completely unnecessary.
在代码中这样做是完全没有必要的。
回答by duffymo
Yes, you can put those calls inside a method and specify your transactions declaratively.
是的,您可以将这些调用放在一个方法中并以声明方式指定您的事务。
You don't need to add that code - Spring can do it for you.
您不需要添加该代码 - Spring 可以为您完成。

