Spring事务回滚失败
我在Service层里面调用两个Dao层的方法。一个方法用于储存一行Investor数据,一个方法用于储存和有Investor主键的Address数据。service层方法如下,注意Investor继承Person,放在同一个数据库表里面。
@Service
public class ServiceImpl implements PortfolioService {
@Autowired
private PersonDao personDao;//Dao层接口
@Transactional(rollbackFor = { Throwable.class })
public void addInvestor(String personCode, String firstName, String lastName, String country, String state,
String street) {
Investor p = new Investor(personCode,firstName,lastName);
int personId = personDao.addPerson(p);//第一个方法添加investor,方法返回该行数据自动生成的主键
Address ad = new Address(street,state, country);
personDao.addAddress(ad,personId);//第二个方法添加address,前面生成的personId会成为Address属性,因为Address对应一个investor
}
}
我必须保证这两个方法的原子性,如果addAddress出现了问题,addPerson必须回滚。但是我的方法始终没有达到回滚的效果。我成功地插入一行person数据,addAddress方法出错,addPerson方法却没有回滚。
以下是相关的xml配置文件和代码
Spring-Hibernate.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:component-scan base-package="dao,pojo,service,pojoView"/>
<!-- 引入property配置文件 -->
<context:property-placeholder location="jdbc.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.mysql.driverClassName}" />
<property name="url" value="${jdbc.mysql.url}" />
<property name="username" value="${jdbc.mysql.username}" />
<property name="password" value="${jdbc.mysql.password}" />
</bean>
<!-- 配置hibernate SessionFactory with a spring plug in -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- hibernate自动扫描 实体类-->
<property name="packagesToScan">
<list>
<value>pojo</value>
<value>pojoView</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.mysql.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${jdbc.hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hiberante.format_sql">true</prop>
</props>
</property>
<property name="configLocations">
<list>
<value>classpath*:hibernate.cfg.xml</value>
</list>
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
下面是我在UnitTest方法里面调用Service层的方法。
PersonTest.java
public class PersonTest extends BaseTest {
@Autowired
private PortfolioService ps;
public PersonTest() {
System.out.println("PersonTest构造方法");
}
@Test
public void test8() {
ps.addInvestor("kk5", "m4", "chrow", "Cua", "Nebska", "D stret");
}
BaseTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:Spring-Hibernate.xml")
public class BaseTest {
@Before
public void init() {
System.out.println("initializing");
}
}
PersonDaoImpl.java
@Repository
public class PersonDaoImpl implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
public void addAddress(Address ad,int personId) {
Session session = sessionFactory.openSession();
//ad.setPersonId(personId);
session.save(ad);
session.close();
}
public int addPerson(Person p) {
Session session = sessionFactory.openSession();
session.save(p);
int personId = p.getPersonId();
session.close();
return personId;
}
}
请大神指点一下这个为什么不能回滚,测试方法test8()没有报错,只是Investor的数据被存入了数据库,没有因为addAddress的异常而回滚。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你这是两个事务呀,
openSession
是开启一个新事物,如果你要保证ACID,所有操作必须在同一个事务中