这是关于Spring 在服务层OpenSessionInViewFilter使用 @Transactional注释.
我经历了这么多的堆栈溢出帖子,但仍然困惑我是否应该使用OpenSessionInViewFilter或不避免LazyInitializationException
如果有人帮我找到以下查询的答案将是很大的帮助.
OpenSessionInViewFilter在具有复杂模式的应用程序中使用是不好的做法.N+1问题OpenSessionInViewFilter它是否意味着@Transactional不需要?下面是我的Spring配置文件
<context:component-scan base-package="com.test"/>
<context:annotation-config/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="resources/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<!--
<prop key="hibernate.hbm2ddl.auto">create</prop>
-->
</props>
</property>
</bean> …Run Code Online (Sandbox Code Playgroud) 我仍然试图围绕@Transactional 的工作原理进行思考。
我@Transactional对 Service 类的方法进行了@Modifying注释,对 Repository 类中的方法进行了注释。带@Transactional注释的方法是否适用于带注释的 Repository 中的方法@Modifying?
我的理解:
@Transactional在@Transactional( readOnly = true )没有数据的类的方法上写入数据库,而在使用 时@Transactional,数据写入数据库。
修改查询
- 修改方法签名只能返回
void,Integer或者int- 更新查询必须是事务性的,标记为
@Transactional- Spring Data 将删除所有未刷新的更改
EntityManager,更改为@Modifying(clearAutomatically=false)
正如第二点所说的@Modifying查询必须有@Transactional(readOnly=false),所以我们可以在@Service方法调用@Repository级别或方法级别调用中添加它。如果在@Service级别添加它也适用于@Respository从@Service级别方法调用中调用的方法?
例子:
@Service
class AnimalServiceImpl implements AnimalService {
@Autowire
AnimalRepository animalRepository;
@Override
@Transactional
public void persistAnimal() {
....
animalRepository.save();
}
@Override
@Transactional(readOnly …Run Code Online (Sandbox Code Playgroud) 在Spring中,你不能简单地@Transactional从同一个实例调用方法,因为AOP代理的东西.自我注入并从自代理实例调用该方法是不是一个好主意?你看到任何缺点吗?
我在mule flow中遇到数据库事务的问题.这是我定义的流程:
<flow name="createPortinCaseServiceFlow">
<vm:inbound-endpoint path="createPortinCase" exchange-pattern="request-response">
<custom-transaction action="ALWAYS_BEGIN" factory-ref="muleTransactionFactory"/>
</vm:inbound-endpoint>
<component>
<spring-object bean="checkIfExists"/>
</component>
<component>
<spring-object bean="createNewOne"/>
</component>
</flow>
Run Code Online (Sandbox Code Playgroud)
我们的想法是,在checkIfExists中,我们验证是否存在某些数据(在数据库中)是否存在异常.如果不是,我们去createNewOne并创建一个新数据.
如果我们同时运行流程,则会在createNewOne中多次创建新对象,并且它们不应该像我们之前调用checkIfExists一样.这意味着交易无法正常运作.
既createNewOne和checkIfExists有以下注释:
@Transactional(propagation = Propagation.MANDATORY)
Run Code Online (Sandbox Code Playgroud)
muleTransactionFactory的定义如下所示
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="teleportNpDataSource"/>
<property name="entityManagerFactory" ref="npEntityManagerFactory"/>
<property name="nestedTransactionAllowed" value="true"/>
<property name="defaultTimeout" value="${teleport.np.tm.transactionTimeout}"/>
</bean>
<bean id="muleTransactionFactory" class="org.mule.module.spring.transaction.SpringTransactionFactory">
<property name="manager" ref="transactionManager"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
我已经设置了TRACE日志级别(如@Shailendra建议的那样),我发现事务在所有spring bean中都被重用:
00:26:32.751 [pool-75-thread-1] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Participating in existing transaction
Run Code Online (Sandbox Code Playgroud)
在日志中,事务同时提交,这意味着这些事务是正确创建的,但是并发执行会导致问题.
我在我的项目基于注释的事务管理中使用(我使用@Transactional注释一些方法).我想全局设置隔离级别(而不是将其作为每个@Transactional注释的参数).
是否有可能在XML中配置?目前我的xml配置包含
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式将隔离添加到tx:annotation-driven?
我找到了以下主题:JdbcTemplate与TransactionManager如何一起工作?
第一句话:
据我所知,DataSourceTransactionManager将JDBC连接从指定的DataSource绑定到当前线程,允许每个DataSource一个线程绑定连接.如果它是一个连接池,它将采用一个可用的连接.
......正是我想知道的.
使用事务管理器时,您最终是否拥有自己的单个连接的每个线程?此外,该连接存在多长时间?同一个线程是否在单个请求中使用相同的连接,或者还有其他事情在进行?我只是想了解一下当你有一个事务管理器时Spring正在做什么,而当你没有事务管理器时(无论你是否真的有一个事务).
我使用SpringBatch 2.1.7发布核心和Infrastructure jar来读取CSV文件并将其保存到DB.
集成我的代码与Spring石英调度程序运行每分钟,批处理工作正常,读取和写入但它失败了错误"org.springframework.dao.OptimisticLockingFailureException:尝试更新步骤执行id = 1与错误的版本(2 ),当前版本是1"
由于Tx冲突.请建议我如何解决此问题.
我有一个问题:为什么当我们使用@Scheduledand 注释方法时@Transaction,事务不起作用?我知道@Scheduled调用我的类而不是Spring创建的代理类,但无法理解这种行为.
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserServiceImpl implements UserService {
@Override
@Scheduled(fixedRateString = "${somestring}",initialDelayString = "${anotherstring}")
@Transactional
public void doSomething() {
}
}
Run Code Online (Sandbox Code Playgroud)
我有两个解决这个问题的方法:
从Scheduled方法调用代理.
用代理ConcurrentTaskScheduler
对象实现和替换ScheduledMethodRunnable(与我的类一起)的对象ScheduledMethodRunnable.
但是这种解决方案非常不方便.
你能解释一下为什么会@Scheduled这样吗?
谢谢!
我有一个基于泛型的DAO类,它是我项目中所有其他DAO类的基础,并包含常用功能:
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
// ....
}
public void save(E entity) {
// ...
}
public void delete(E entity) {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在我的项目中,我使用多个数据源,指向不同的数据库,因此,我有多个会话和事务管理器:
<bean id="factory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="source1" />
</bean>
<bean id="manager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="factory1" />
</bean>
<bean id="factory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="source2" />
</bean>
<bean id="manager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="factory2" />
</bean>
Run Code Online (Sandbox Code Playgroud)
现在我想创建几个DAO,在不同的数据库上运行:
@Repository
@Transactional("manager1")
public class …Run Code Online (Sandbox Code Playgroud) 在春天,如果我有:
ServiceA.serviceA() -> ServiceB.serviceB() -> ServiceC.serviceC() ->ServiceD.serviceD()
哪里ServiceD.serviceD()可以抛出运行时异常:MyRuntimeException,它被传播回ServiceA.serviceAcatch块.我穿上哪种服务是否重要@Transactional(noRollbackFor=[MyRuntimeException.class])?
将它放在任何服务上有什么区别吗?
注意:我的所有服务都标记为@Transactional
spring ×9
java ×7
transactions ×2
hibernate ×1
mule ×1
spring-aop ×1
spring-batch ×1
spring-boot ×1