gpt4 book ai didi

java - Spring事务隔离不起作用

转载 作者:行者123 更新时间:2023-11-30 11:22:29 25 4
gpt4 key购买 nike

我正在制作一个非常简单的示例来测试 Spring 隔离。我有 2 个非常相似的 Schedule 类:

@Service("manager1")
public class Manager1 {

private Service1 service1;

@Scheduled(fixedDelay = 15000)
public void sendScheduledCampaigns() {
service1.changeCredits();
}
...

@Service("manager2")
public class Manager2 {

private Service2 service2;

@Scheduled(fixedDelay = 15000)
public void sendScheduledCampaigns() {
service2.changeCredits();
}
...

此外,我有 2 个非常相似的服务类:

@Service("service1")
@Transactional
public class Service1 {

private UserService userService;

private static Logger log = Logger.getLogger(Service1.class);

public void changeCredits() {
User user = userService.getUserById(1);

log.info("Service1 previous credits: " + user.getCredits());
int newCredit = user.getCredits() + 5;
user.setCredits(newCredit);

log.info("Service1 new credits: " + user.getCredits());
}
...

@Service("service2")
@Transactional
public class Service2 {

private UserService userService;

private static Logger log = Logger.getLogger(Service2.class);

public void changeCredits() {

User user = userService.getUserById(1);

log.info("Service2 previous credits: " + user.getCredits());
int newCredit = user.getCredits() + 5;
user.setCredits(newCredit);

log.info("Service2 new credits: " + user.getCredits());
}

运行这段代码后,我可以看到当两个事务同时执行时,两个事务都从数据库中获取相同的值。因此,他们忽略了另一个的修改。我想这是事务隔离中的一个错误:

INFO  27 Feb 2014 14:14:22 - Service1 previous credits: 0
INFO 27 Feb 2014 14:14:22 - Service2 previous credits: 0
INFO 27 Feb 2014 14:14:22 - Service1 new credits: 5
INFO 27 Feb 2014 14:14:22 - Service2 new credits: 5

此处的积分值应为 10

此后,由于两个进程没有同时执行,计算开始正常:

Feb 27, 2014 2:14:23 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Feb 27, 2014 2:14:23 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Feb 27, 2014 2:14:23 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 10698 ms
INFO 27 Feb 2014 14:14:37 - Service2 previous credits: 5
INFO 27 Feb 2014 14:14:37 - Service2 new credits: 10
INFO 27 Feb 2014 14:14:38 - Service1 previous credits: 10
INFO 27 Feb 2014 14:14:38 - Service1 new credits: 15

我正在使用 MYSQL,这些是我的任务和事务配置:

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="100"/>
<task:scheduler id="myScheduler" pool-size="100"/>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
<property name="packagesToScan" value="test.domain" />
</bean>

出于某种原因,我的默认隔离级别是null。我是从这里得到的:

log.info("isolation: " +TransactionSynchronizationManager.getCurrentTransactionIsolationLevel()); 

因此,我尝试更改两个服务的隔离级别:

@Service("service1")
@Transactional(isolation=Isolation.REPEATABLE_READ)
public class Service1 {

@Service("service2")
@Transactional(isolation=Isolation.REPEATABLE_READ)
public class Service2 {

结果还是错了。

你知道为什么会这样吗?

提前致谢。

最佳答案

在这种情况下,@Transaction 使用默认隔离,这取决于您使用的数据库,尝试使用隔离属性和 Isolation.REPEATABLE_READ 来获得所需的行为。

Enum(Isolation) Enumeration that represents transaction isolation levels for use with the Transactional annotation, corresponding to the TransactionDefinition interface.

http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/annotation/Isolation.html#DEFAULT

当一个事务被允许从一个已被另一个正在运行的事务修改但尚未提交的行中读取数据时,就会发生脏读。

关于java - Spring事务隔离不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21655113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com