spring声明式事务 主动抛出错误不回滚
spring声明式事务 主动抛出异常不回滚
说明:事务配置用的声明式事务,就没有用@Transactional注解了,Controller和Service都是用的注解,整个流程是Controller--Service接口-Service实现类-实体类初始化DAO接口-DAO接口-DAo实现类(数据库操作)。我在Service里面主动抛出异常,两种方式保存,为什么getHibernateTemplate().saveOrUpdate() 的方式保存,事务不会回滚,而用this.getSession.merge(domain)的方式 就会回滚。
下面贴上代码:
Controller:
Service接口:
Service实现类:
Supplier实体类:
应该是DAO层了吧。。接口:
实现类:
下面是配置文件:
web.xml我加了openSessionView:
事务配置:
已经纠结我两天了 请大神帮忙解答一下 因为项目之前没有用注解方式做 (之前Service是有事务管理的,我加了@Service注解后就没事务了。。) 之前做的 保存都是用 getHibernateTemplate().saveOrUpdate(domain); 来保存的,所以必须要用这个来保存。。但是他抛异常不回滚 急死我了。 web.xml的openSessionView是我后来自己加进去的(不加就报错)
------解决思路----------------------
你tx:advice也没配这个方法啊
用注解@transactional多简单,不容易出错
------解决思路----------------------
使用spring的注解式事务,很简单的,自己google下或者上spring官网看它的文档例子.注解式事务声明起来简单,方便,不过有个弊端就是不能向xml配置式事务那种可以针对通用方法全局配置事务属性
------解决思路----------------------
Spring 事务处理 http://qtdebug.com/java/14.%20Spring%20%E4%BA%8B%E5%8A%A1%E5%A4%84%E7%90%86.html
说明:事务配置用的声明式事务,就没有用@Transactional注解了,Controller和Service都是用的注解,整个流程是Controller--Service接口-Service实现类-实体类初始化DAO接口-DAO接口-DAo实现类(数据库操作)。我在Service里面主动抛出异常,两种方式保存,为什么getHibernateTemplate().saveOrUpdate() 的方式保存,事务不会回滚,而用this.getSession.merge(domain)的方式 就会回滚。
下面贴上代码:
Controller:
@Controller
@RequestMapping("/supplier")
public class SupplierController {
@Resource
private SupplierService supplierService;
@RequestMapping("/saveOrUpdate")
public ModelAndView saveOrUpdate(HttpServletRequest request, HttpServletResponse response,Supplier supplier) throws Exception {
supplierService.saveOrUpdateSupplier(supplier);
return null;
}
}
Service接口:
public interface SupplierService {
void saveOrUpdateSupplier(Supplier supplier);
}
Service实现类:
@Service
public class SupplierServiceImpl implements SupplierService{
@Override
public void saveOrUpdateSupplier(Supplier supplier) {
supplier.saveOrUpdate();
throw new RuntimeException("1111"); //主动抛出异常,测试事务回不回滚
}
}
Supplier实体类:
public class Supplier extends AbstractDomain {
//名称
private String name;
//地址
private String address;
//联系人
private String linkMan;
//联系电话
private String linkTel;
//邮件
private String email;
private static StockRepository stockRepository;
public Supplier() {
}
private static StockRepository getStockRepository(){
if(stockRepository == null){
stockRepository = InstanceFactory.getInstance(StockRepository.class);
}
return stockRepository;
}
public void saveOrUpdate() {
getStockRepository().saveOrUpdate(this);
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public String getLinkMan() {
return linkMan;
}
public String getLinkTel() {
return linkTel;
}
public String getEmail() {
return email;
}
}
应该是DAO层了吧。。接口:
public interface StockRepository {
void saveOrUpdate(Domain domain);
}
实现类:
public class StockRepositoryHibernate extends AbstractRepositoryHibernate implements StockRepository{
@Override
public void saveOrUpdate(Domain domain){
//this.getSession().merge(domain); //用这个就能回滚
getHibernateTemplate().saveOrUpdate(domain); //用这个不能回滚
}
}
下面是配置文件:
web.xml我加了openSessionView:
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
事务配置:
<aop:config>
<aop:advisor advice-ref="applicationAdvisor"
pointcut="execution(* com.test.service.*.*(..))"/>
</aop:config>
<tx:advice id="applicationAdvisor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
<tx:method name="loadUser*" propagation="REQUIRED"/>
<tx:method name="read*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="load*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="set*Service" propagation="SUPPORTS"/>
<tx:method name="check*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="download*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="isExist*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="list*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="upload*" propagation="SUPPORTS"/>
<tx:method name="send*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="rollbackOnCommitFailure" value="true"/>
</bean>
已经纠结我两天了 请大神帮忙解答一下 因为项目之前没有用注解方式做 (之前Service是有事务管理的,我加了@Service注解后就没事务了。。) 之前做的 保存都是用 getHibernateTemplate().saveOrUpdate(domain); 来保存的,所以必须要用这个来保存。。但是他抛异常不回滚 急死我了。 web.xml的openSessionView是我后来自己加进去的(不加就报错)
------解决思路----------------------
你tx:advice也没配这个方法啊
用注解@transactional多简单,不容易出错
------解决思路----------------------
使用spring的注解式事务,很简单的,自己google下或者上spring官网看它的文档例子.注解式事务声明起来简单,方便,不过有个弊端就是不能向xml配置式事务那种可以针对通用方法全局配置事务属性
------解决思路----------------------
Spring 事务处理 http://qtdebug.com/java/14.%20Spring%20%E4%BA%8B%E5%8A%A1%E5%A4%84%E7%90%86.html