Spring @Transactional未同步

时间:2016-07-16 06:44:49

标签: java spring transactions

这是我的代码:

@Getter
@Setter
@Entity
@ToString
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

public interface UserRepository extends JpaRepository<User, Long> {
}

@Service("service1")
public class UserService1 implements Runnable {
    @Autowired
    private UserRepository userRepository;
    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void run() {
        System.out.println("*** Start Transaction 1 ***");
        User user = userRepository.findOne(1L);
        user.setName("user " + Math.random());
        System.out.println("Sleeping ...");
        try {Thread.sleep(10000);} catch (InterruptedException e) {}
        System.out.println("Updating user in Transaction 1... ");
        userRepository.save(user);
        System.out.println("*** Completed 1 ***");
    }
}

@Service("service2")
public class UserService2 implements Runnable {
    @Autowired
    private UserRepository userRepository;
    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void run() {
        System.out.println("*** Start Transaction 2 ***");
        User user = userRepository.getOne(1L);
        user.setName("User_service2");
        userRepository.save(user);
        System.out.println("*** Completed 2 ***");
    }
}

@SpringBootApplication
@EnableTransactionManagement
public class Main {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
        Executor e = Executors.newFixedThreadPool(2);
        e.execute((Runnable) context.getBean("service1"));
        Thread.sleep(2000);
        e.execute((Runnable) context.getBean("service2"));
    }
}

我有两个具有相同隔离级别的服务,都进行实体更新。完全开始后第二次开始(睡眠2秒)。第一个是“慢”的。

由于isolation = SERIALIZABLE我希望这会为整个用户表创建一个锁,而执行它的任何服务都可以工作: 在我的情况下,service2应该等到service1完成它的工作,但这不会发生。

有人可以澄清为什么它不起作用?也许我在描述中遗漏了一些东西 感谢。

更新1:

添加了系统输出。

*** Start Transaction 1 ***
Hibernate: select user0_.id as id1_0_0_, user0_.name as name2_0_0_ from user user0_ where user0_.id=?
Sleeping ...
*** Start Transaction 2 ***
Hibernate: select user0_.id as id1_0_0_, user0_.name as name2_0_0_ from user user0_ where user0_.id=?
*** Completed 2 ***
Hibernate: update user set name=? where id=?
Updating user in Transaction 1... 
*** Completed 1 ***
Hibernate: update user set name=? where id=?
2016-07-16 11:47:29.267  WARN 15656 --- [pool-2-thread-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1213, SQLState: 40001
2016-07-16 11:47:29.267 ERROR 15656 --- [pool-2-thread-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Deadlock found when trying to get lock; try restarting transaction

更新2:

DB:MySQL 5.6.25

0 个答案:

没有答案