我有一组@Servicebean从一个抽象类继承核心功能.我用@Service和标记了每个具体的子类服务@Transactional.抽象超类包含每个服务的公共入口点方法.换句话说,我有类似于以下内容:
abstract class AbstractService {
public void process() {
// Do common initialisation code here
processSpecific();
// Do common completion code here
}
abstract protected void processSpecific();
}
@Service @Transactional
public class FirstSpecificService extends AbstractService {
protected void processSpecific() {
// Do specific processing code here
}
}
@Service @Transactional
public class SecondSpecificService extends AbstractService {
protected void processSpecific() {
// Do different specific processing code here
}
}
Run Code Online (Sandbox Code Playgroud)
每个具体子类服务中的特定代码对DAO层进行多次调用以对数据库进行更改,这些更改具有REQUIRED事务传播类型.
现在使用上面定义的服务,我发现在这些具体的子类服务的任何代码中都没有当前事务,并且每次调用DAO层都是创建一个新事务,执行更改,提交事务和返回.
但是,如果我注释抽象超类 …
我在堆栈溢出文章中看到很多评论我发现@Transactional与@Service或@Controller一起使用的某些事情
"通常,应该在服务层进行交易."
"正常情况是在服务层级注释"
"认为事务属于服务层.它是了解工作单元和用例的人.如果你有几个DAO注入到需要在单个事务中协同工作的服务,那么这是正确的答案." [资源]
使用带有@service层的@transactional的缺点
如果我有2个方法,例如saveUser()和saveEmail()(因为我将电子邮件存储在数据库中以便稍后发送 - 就像一个队列)我会在我的服务中创建一个方法saveUserAndSendEmail(用户用户),它将是事务性的.[资源]
这意味着我在服务层创建了许多方法,而不是一个Save Generic Method,如下所示
public <T> long save(T entity) throws DataAccessException {
Session session = sessionFactory.getCurrentSession();
long getGenVal=(Long) session.save(entity);
return getGenVal;
}
Run Code Online (Sandbox Code Playgroud)
根据上面的解决方案,这意味着我们有很多方法,如以下LOL ..
public <T> long saveAccount(T entity)....
public <T> long saveWithAuditLog(T entity, K entity1)....
public <T> long saveWithAuditLogAndEntries(T entity, K entity, M entity)....
克服这种情况
我在@Controller中使用@Transactional,只需制作一个通用保存方法,并使用这个简单的保存方法保存所有实体/模型.如果任何方法无法保存,则控制器中的所有事务都会成功回滚.
确保@Transactional应与@Controller一起使用的其他情况
在@Controller中:
pt.save(entity1);
pt.save(entity2);
int a = 2/0;
pt.save(entity3);
Run Code Online (Sandbox Code Playgroud)
如果@Transactional on Service,前2个实体成功保存,但第三个不回滚所有事务
如果@Tratroller上的@Transactional,所有事务回滚都会发生异常
为什么堆栈溢出问道,"不要在控制器中进行事务处理.将它们放在服务层类中."? [资源]
对于WebApplicationContext,我应该@Transactional在控制器或服务中添加注释吗?Spring文档让我有些困惑.
这是我的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Alpha v0.02</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Run Code Online (Sandbox Code Playgroud)
这是我的application-context.xml,它定义了一个spring dispatcher servlet:
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<tx:annotation-driven />
<context:component-scan base-package="com.visitrend" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" …Run Code Online (Sandbox Code Playgroud) 那么Grails Declarative Transactions就有一点了.它说:
grails.transaction.Transactional注释最初是在Grails 2.3中引入的.在2.3之前,使用了Spring的@Transactional注释.
但我似乎无法找出这两个注释之间的主要区别是什么.为什么未来的版本中没有使用Spring的注释?
我正在使用Spring 3和Hibernate 3.我正在尝试配置Spring声明式事务,但无论我尝试什么,Spring事务都没有开始.
这是我的配置
文件:applicationContext-hibernate.xml
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="mdbDataSource" class="org.apache.commons.dbcp.BasicDataSource">
...
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="mdbDataSource" />
<property name="annotatedClasses">
.....
</bean>
Run Code Online (Sandbox Code Playgroud)
我有一个ServiceLocatorImpl类,它实现了ServiceLocator接口
@Service("serviceLocator")
@Transactional
public class ServiceLocatorImpl implements ApplicationContextAware, Serializable, ServletContextAware, ServiceLocator {
public ResultObject executeService( Map objArgs )
{
if(TransactionSynchronizationManager.isActualTransactionActive()) {
LOGGER.debug("ServiceLocator:executeService - Active transaction found");
} else {
LOGGER.error("No active transaction found");
}
......
}
....
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我的所有配置都是正确的.但是,当调用executeService方法时,TransactionSynchronizationManager.isActualTransactionActive()始终返回false.
请帮我解决这个问题.如果需要更多信息,请告诉我.
更新: 我已将ServiceLocator连接到其他类之一,如下所示:
@Autowired
private ServiceLocator serviceLocator; // ServiceLocator …Run Code Online (Sandbox Code Playgroud) 我有一个使用@Transactional注释的方法.我从我的数据库中检索一个对象,更改一个字段,然后从该方法返回.在不保存我的对象的情况下,数据库无论如何都会更新,这很奇怪.
你能告诉我如何避免这种行为吗?
好的,所以我终于屈服于同伴压力并开始在我的网络应用程序中使用Spring: - )...
所以我试图让事务处理工作起作用,而我似乎无法得到它.
我的Spring配置如下所示:
<?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:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="groupDao" class="mil.navy.ndms.conops.common.dao.impl.jpa.GroupDao" lazy-init="true">
<property name="entityManagerFactory" ><ref bean="entityManagerFactory"/></property>
</bean>
<!-- enables interpretation of the @Required annotation to ensure that dependency injection actually occures -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<!-- enables interpretation of the @PersistenceUnit/@PersistenceContext annotations providing convenient
access to EntityManagerFactory/EntityManager -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<!-- uses the persistence unit defined in the META-INF/persistence.xml JPA configuration file -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="CONOPS_PU" />
</bean>
<!-- …Run Code Online (Sandbox Code Playgroud) 简单说明:"交易"和"非交易"之间有什么区别?
在我的情况下,我在阅读"MDM"的以下定义时提出了这个问题:
"在计算中,主数据管理"(MDM)包括一组过程和工具,它们一致地定义和管理组织的非事务性数据实体(可能包括参考数据).
在下面的代码片段(Spring 3)中:
@Transactional("txManager")
public class DaoHolder {
@Transactional(value="txManager", readOnly=false, propagation=Propagation.REQUIRES_NEW, rollbackFor={Exception.class})
private void runTransactionalMethod() throws Exception {
dao1.insertRow();
dao2.insertRow();
//throw new Exception();
}
//...
}
Run Code Online (Sandbox Code Playgroud)
上面的代码以事务方式正常工作 - 特别是,当没有抛出异常时,每个dao操作都被提交(到2个不同的数据源).抛出异常时,每个dao操作都会回滚.
我的问题是:它为什么有效?我读到的任何地方我都被告知在处理多个数据源时使用JtaTransactionManager.我不想使用JTA.如果我让它在HibernateTransactionManager下运行会有什么后果?
感兴趣的更多细节:
每个数据源的定义如下:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="${jdbc.initial_size}" />
<property name="maxActive" value="${jdbc.max_active}" />
</bean>
Run Code Online (Sandbox Code Playgroud)
每个会话工厂的定义如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
... multiple …Run Code Online (Sandbox Code Playgroud) 我使用的是Spring 3.2,Hibernate和JUnit 4.
我的Dao课程如下:
@Transactional public class SomeDaoImpl implements SomeDao {
如果直接从Web应用程序执行,则对此工作进行更新操作.但是,我发现执行更新方法的junit集成测试实际上并不会保留更改.在执行junit方法时,事务是否会滚动事务?
transactional ×10
spring ×7
hibernate ×4
service ×3
controller ×2
java ×2
jpa ×2
transactions ×2
annotations ×1
grails ×1
grails-2.3 ×1
grails-2.5 ×1
junit4 ×1
spring-mvc ×1
spring-test ×1