java Spring 事务未提交
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2992526/
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
Spring transactions not committing
提问by Clinton Bosch
I am struggling to get my spring managed transactions to commit, could someone please spot what I have done wrong. All my tables are mysql InnonDB tables. My RemoteServiceServlet (GWT) is as follows:
我正在努力让我的 spring 管理事务提交,有人可以发现我做错了什么。我所有的表都是 mysql InnonDB 表。我的 RemoteServiceServlet (GWT) 如下:
public class TrainTrackServiceImpl extends RemoteServiceServlet implements TrainTrackService {
@Autowired
private DAO dao;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
AutowireCapableBeanFactory beanFactory = ctx.getAutowireCapableBeanFactory();
beanFactory.autowireBean(this);
}
@Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
public UserDTO createUser(String firstName, String lastName,
String idNumber, String cellPhone, String email, int merchantId) {
User user = new User();
user.setFirstName(firstName);
user.setLastName(lastName);
user.setIdNumber(idNumber);
user.setCellphone(cellPhone);
user.setEmail(email);
user.setDateCreated(new Date());
Merchant merchant = (Merchant) dao.find(Merchant.class, merchantId);
if (merchant != null) {
user.setMerchant(merchant);
}
// Save the user.
dao.saveOrUpdate(user);
UserDTO dto = new UserDTO();
dto.id = user.getId();
dto.firstName = user.getFirstName();
dto.lastName = user.getLastName();
return dto;
}
The DAO is as follows:
DAO 如下:
public class DAO extends HibernateDaoSupport {
private String adminUsername;
private String adminPassword;
private String godUsername;
private String godPassword;
public String getAdminUsername() {
return adminUsername;
}
public void setAdminUsername(String adminUsername) {
this.adminUsername = adminUsername;
}
public String getAdminPassword() {
return adminPassword;
}
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}
public String getGodUsername() {
return godUsername;
}
public void setGodUsername(String godUsername) {
this.godUsername = godUsername;
}
public String getGodPassword() {
return godPassword;
}
public void setGodPassword(String godPassword) {
this.godPassword = godPassword;
}
public void saveOrUpdate(ModelObject obj) {
getHibernateTemplate().saveOrUpdate(obj);
}
And my applicationContext.xml is as follows:
而我的 applicationContext.xml 如下:
<context:annotation-config/>
<context:component-scan base-package="za.co.xxx.traintrack.server"/>
<!-- Application properties -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:${user.dir}/@propertiesFile@</value>
</list>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${connection.dialect}</prop>
<prop key="hibernate.connection.username">${connection.username}</prop>
<prop key="hibernate.connection.password">${connection.password}</prop>
<prop key="hibernate.connection.url">${connection.url}</prop>
<prop key="hibernate.connection.driver_class">${connection.driver.class}</prop>
<prop key="hibernate.show_sql">${show.sql}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">60</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>za.co.xxx.traintrack.server.model.Answer</value>
<value>za.co.xxx.traintrack.server.model.Company</value>
<value>za.co.xxx.traintrack.server.model.CompanyRegion</value>
<value>za.co.xxx.traintrack.server.model.Merchant</value>
<value>za.co.xxx.traintrack.server.model.Module</value>
<value>za.co.xxx.traintrack.server.model.Question</value>
<value>za.co.xxx.traintrack.server.model.User</value>
<value>za.co.xxx.traintrack.server.model.CompletedModule</value>
</list>
</property>
</bean>
<bean id="dao" class="za.co.xxx.traintrack.server.DAO">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="adminUsername" value="${admin.user.name}"/>
<property name="adminPassword" value="${admin.user.password}"/>
<property name="godUsername" value="${god.user.name}"/>
<property name="godPassword" value="${god.user.password}"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
If I change the sessionFactory property to be autoCommit=true then my object does get persisited.
如果我将 sessionFactory 属性更改为 autoCommit=true 那么我的对象就会被持久化。
<prop key="hibernate.connection.autocommit">true</prop>
采纳答案by axtavt
When GWT calls createUser, this call doesn't go through a Spring's transactional proxy. In order to use @Transactionalyou can introduce additional level of indirection:
当 GWT 调用时createUser,此调用不会通过 Spring 的事务代理。为了使用,@Transactional您可以引入额外的间接级别:
public class TrainTrackServiceWrapper extends RemoteServiceServlet implements TrainTrackService {
@Autowired
private TrainTrackServiceImpl impl;
...
public UserDTO createUser(String firstName, String lastName,
String idNumber, String cellPhone, String email, int merchantId) {
return impl.createUser(firstName, lastName, idNumber, cellPhone, email, merchantId);
}
}
public class TrainTrackServiceImpl implements TrainTrackService {
@Autowired
private DAO dao;
@Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
public UserDTO createUser(String firstName, String lastName,
String idNumber, String cellPhone, String email, int merchantId) {
...
}
}
EDIT: You may also use spring4gwtinstead of it.
编辑:您也可以使用spring4gwt代替它。
回答by Alexander
I had a similar problem with transaction not committing therefore creating locks on rows, until I found that I had another DAO (with @transactional annotations in it) that was not participating in the transaction but nevertheless was called before transactional dao. I cleaned up that dao and it worked afterwords.
我有一个类似的问题,事务没有提交,因此在行上创建锁,直到我发现我有另一个 DAO(其中带有 @transactional 注释)没有参与事务,但在事务 dao 之前被调用。我清理了那个 dao,它在后记中起作用了。
回答by Pratip Mondal
Use PROPAGATION_NOT_SUPPORTED like below:
使用 PROPAGATION_NOT_SUPPORTED 如下:
public CustomerReportEntity publishReportInTransaction(final CustomerReportEntity report) {
final TransactionTemplate transactionTemplate = new TransactionTemplate(this.transactionManagerWDB);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
return (CustomerReportEntity) transactionTemplate.execute(new TransactionCallback() {
@Override
public CustomerReportEntity doInTransaction(final TransactionStatus transactionStatus) {
try {
return generateReportinTransaction(report);
} catch (final Exception e) {
report.setReportStatus(ReportStatus.EXCEPTION.getStatus());
pendingProcessorDao.updateStatus(report, "Exception");
return null;
}
}
});
}

