如何解决如果TransactionProxyFactoryBean用于服务层bean,那么是否有必要在dao中驱动事务注释?
| 服务层的接口是:EMS.java:
public interface EMS extends UserDetailsService {
public void saveUser(User user);
}
及其实现:
EMSImpl.java:
@Service(\"emsImpl\")
@Transactional(readOnly=true)
public class EMSImpl implements EMS {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
@Qualifier(\"dao\")
private EMSDao dao;
@Transactional(readOnly=false)
public void saveUser(User user) {
dao.saveUser();
}
}
dao的接口:
EMSDao.java:
public interface EMSDao {
public void saveUser(User user);
}
及其实现:
HibernateEMSDao.java
@Repository(\"EMSDao\")
public class HibernateEMSDao extends HibernateDaoSupport implements EMSDao {
private final Logger logger = LoggerFactory.getLogger(getClass());
private SchemaHelper schemaHelper;
public void setSchemaHelper(SchemaHelper schemaHelper) {
this.schemaHelper = schemaHelper;
}
@Transactional(readOnly=false)
public synchronized void saveUser(final User user) {
Session session = getSessionFactory().getCurrentSession();
session.merge(user);
}
private void storeUser(User user) {
getHibernateTemplate().save(user);
}
public void createSchema() {
try {
getHibernateTemplate().find(\"from User user where user.id = 1\");
} catch (Exception e) {
logger.warn(\"expected database schema does not exist,will create. Error is: \" + e.getMessage());
schemaHelper.createSchema();
User admin = new User();
admin.setUsername(\"admin\");
admin.setName(\"Admin\");
admin.setEmail(\"admin\");
admin.setPassword(\"21232f297a57a5a743894a0e4a801fc3\");
admin.setRoles(new HashSet<Role>(Arrays.asList(new Role(\"admin\",\"ADMINISTRATOR\"))));
logger.info(\"inserting default admin user into database\");
storeUser(admin);
logger.info(\"schema creation complete\");
return;
}
logger.info(\"database schema exists,normal startup\");
}
}
appliactionContext.xml
中的4ѭ由TransactionProxyfactorybean
创建。我也在用<tx:annotation-driven />
完整的applicationContext.xml是:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<beans xmlns=\"http://www.springframework.org/schema/beans\"
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-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd\">
<bean class=\"info.ems.config.EMSConfigurer\"/>
<bean id=\"passwordEncoder\" class=\"org.acegisecurity.providers.encoding.Md5PasswordEncoder\"/>
<bean id=\"ems\" class=\"org.springframework.transaction.interceptor.TransactionProxyfactorybean\">
<property name=\"transactionManager\" ref=\"transactionManager\"/>
<property name=\"target\">
<bean class=\"info.ems.EMSImpl\" init-method=\"init\">
<property name=\"dao\" ref=\"dao\"/>
<property name=\"passwordEncoder\" ref=\"passwordEncoder\"/>
<property name=\"localeList\" value=\"${ems.locales}\"/>
<property name=\"releaseVersion\" value=\"${ems.version}\"/>
<property name=\"releaseTimestamp\" value=\"${ems.timestamp}\"/>
<property name=\"emsHome\" value=\"${ems.home}\"/>
</bean>
</property>
<property name=\"transactionAttributes\">
<props>
<prop key=\"store*\">PROPAGATION_required</prop>
<prop key=\"update*\">PROPAGATION_required</prop>
<prop key=\"remove*\">PROPAGATION_required</prop>
<prop key=\"bulkupdate*\">PROPAGATION_required</prop>
<prop key=\"*\">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager=\"transactionManager\" />
<bean id=\"transactionManager\" class=\"org.springframework.orm.hibernate3.HibernateTransactionManager\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>
<bean id=\"dataSource\" class=\"info.ems.datasource.DataSourceFactory\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"validationQuery\" value=\"${database.validationQuery}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
<bean id=\"sessionFactory\" class=\"org.springframework.orm.hibernate3.LocalSessionfactorybean\">
<property name=\"dataSource\" ref=\"dataSource\"/>
<property name=\"configLocation\">
<value>/WEB-INF/hibernate.cfg.xml</value>
</property>
<property name=\"configurationClass\">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name=\"hibernateProperties\">
<props>
<prop key=\"hibernate.dialect\">${hibernate.dialect}</prop>
<prop key=\"hibernate.show_sql\">${hibernate.show_sql}</prop>
<prop key=\"hibernate.current_session_context_class\">org.hibernate.context.ThreadLocalSessionContext</prop>
</props>
</property>
</bean>
<bean id=\"dao\" class=\"info.ems.hibernate.HibernateEMSDao\" init-method=\"createSchema\">
<property name=\"hibernateTemplate\">
<bean class=\"org.springframework.orm.hibernate3.HibernateTemplate\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>
</property>
<property name=\"schemaHelper\">
<bean class=\"info.ems.hibernate.SchemaHelper\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"hibernateDialect\" value=\"${hibernate.dialect}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
</property>
</bean>
</beans>
我想知道:
在Spring之前处理数据库事务是否正确的配置?
是否需要同时使用ѭ6和ѭ7?
我可以获取示例的任何信息或Web链接都将非常有帮助。
谢谢并恭祝安康。
编辑:从skaffman得到建议后,修改后的appliactionContext.xml:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<beans xmlns=\"http://www.springframework.org/schema/beans\"
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-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd\">
<bean class=\"info.ems.config.EMSConfigurer\"/>
<bean id=\"passwordEncoder\" class=\"org.acegisecurity.providers.encoding.Md5PasswordEncoder\"/>
<bean id=\"ems\" class=\"info.ems.EMSImpl\" init-method=\"init\">
<property name=\"dao\" ref=\"dao\"/>
<property name=\"passwordEncoder\" ref=\"passwordEncoder\"/>
<property name=\"localeList\" value=\"${ems.locales}\"/>
<property name=\"releaseVersion\" value=\"${ems.version}\"/>
<property name=\"releaseTimestamp\" value=\"${ems.timestamp}\"/>
<property name=\"emsHome\" value=\"${ems.home}\"/>
</bean>
<tx:annotation-driven transaction-manager=\"transactionManager\" />
<bean id=\"transactionManager\" class=\"org.springframework.orm.hibernate3.HibernateTransactionManager\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>
<bean id=\"dataSource\" class=\"info.ems.datasource.DataSourceFactory\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"validationQuery\" value=\"${database.validationQuery}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
<bean id=\"sessionFactory\" class=\"org.springframework.orm.hibernate3.LocalSessionfactorybean\">
<property name=\"dataSource\" ref=\"dataSource\"/>
<property name=\"configLocation\">
<value>/WEB-INF/hibernate.cfg.xml</value>
</property>
<property name=\"configurationClass\">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name=\"hibernateProperties\">
<props>
<prop key=\"hibernate.dialect\">${hibernate.dialect}</prop>
<prop key=\"hibernate.show_sql\">${hibernate.show_sql}</prop>
<prop key=\"hibernate.current_session_context_class\">org.hibernate.context.ThreadLocalSessionContext</prop>
</props>
</property>
</bean>
<bean id=\"dao\" class=\"info.ems.hibernate.HibernateEMSDao\" init-method=\"createSchema\">
<property name=\"hibernateTemplate\">
<bean class=\"org.springframework.orm.hibernate3.HibernateTemplate\">
<property name=\"sessionFactory\" ref=\"sessionFactory\"/>
</bean>
</property>
<property name=\"schemaHelper\">
<bean class=\"info.ems.hibernate.SchemaHelper\">
<property name=\"driverClassName\" value=\"${database.driver}\"/>
<property name=\"url\" value=\"${database.url}\"/>
<property name=\"username\" value=\"${database.username}\"/>
<property name=\"password\" value=\"${database.password}\"/>
<property name=\"hibernateDialect\" value=\"${hibernate.dialect}\"/>
<property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
</bean>
</property>
</bean>
</beans>
解决方法
在Spring之前处理数据库事务是否正确的配置?
它是完全有效的,但是令人困惑并且重复工作。这可能会产生两层事务代理,尽管我怀疑这样做的行为会有所不同。
如您所说,您可能不想同时使用
TransactionProxyFactoryBean
和<tx:annotation-driven />
。
您的“ 6”配置使用外部化的方法名称模式来确定哪些方法获得哪种事务语义。很好,尽管使用Spring的当前版本通常更容易使用注释,而不是TransactionProxyFactoryBean
上的transactionAttributes
属性。
给定您的配置,我建议您摆脱显式的TransactionProxyFactoryBean
bean定义(<tx:annotation-driven />
将在幕后根据需要创建自己的一个)。用未修饰的“ 19”替换,“ 7”将自动生成事务代理。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。