Java 我需要锁定DB表还是只同步从不同线程调用时写入DB的方法?

Java 我需要锁定DB表还是只同步从不同线程调用时写入DB的方法?,java,database,synchronization,locking,eclipselink,Java,Database,Synchronization,Locking,Eclipselink,我正在开发一个将由多个客户机使用的web服务。我使用EclipseLink作为JPA提供商。当从客户端调用web服务中的方法时,我注意到EclipseLink使用线程池中的一个线程来调用该方法,这意味着可以同时从该线程池中的不同线程调用该方法 在一些方法中,我对数据库中的一些表进行了一些关键的写操作,并且我需要实现某种锁定机制。在写入数据库时同步这些方法是一种好的做法,还是需要在MySQL中锁定整个表 在伪代码中,有些写操作如下所示: 1. insert_into_TableA(getLa

我正在开发一个将由多个客户机使用的web服务。我使用EclipseLink作为JPA提供商。当从客户端调用web服务中的方法时,我注意到EclipseLink使用线程池中的一个线程来调用该方法,这意味着可以同时从该线程池中的不同线程调用该方法

在一些方法中,我对数据库中的一些表进行了一些关键的写操作,并且我需要实现某种锁定机制。在写入数据库时同步这些方法是一种好的做法,还是需要在MySQL中锁定整个表

在伪代码中,有些写操作如下所示:

   1. insert_into_TableA(getLastInsertedIdInTableA + 1);
   2. insert_into_TableB(getLastInsertedIdInTableB + 1);
   3. int id_A = getLastInsertedIdInTableA + 1;
   4. int id_B = getLastInsertedIdInTableB + 1;
   5. insert_into_TableAB(id_A, id_B);
数据库结构如下:

TableA          TableAB         TableB
pk tableA_id    pk tableA_id    pk tableB_id
                pk tableB_id
我的第二个问题:我的表中没有使用
autoincrement
,因此在插入新行时,获取最后一个插入行的ID,然后将其增量1以插入新行,这是一种好的做法吗?或者我可以使用EclipseLink中的一些好方法来为我做到这一点

你需要的是一个”

通常,容器将确保在新请求进入时启动新事务,并在处理请求的代码完成后提交事务(除非引发异常)

问题是
getLastInsertedId
-这不起作用。不同的事务可能在这里看到相同的值。解决方案是让数据库为您找出一个新的免费ID


改为使用“标识列”。在MySQL中就是这样。

为什么您认为需要锁定表?MySQL应该处理并发性。毕竟,这就是数据库的用途。@a_horse_和_no_name:Yes,MySQL正在处理并发性,但在LogisC位于应用程序级别的情况下(如我的情况下)则不会。两个不同的事务,如下面所述的Aaron Digulla,可以获得相同的getLastInsertedIdInTableA值,并发处理程序将插入具有相同
getLastInsertedIdInTableA
值作为
tableA\u id
的新行,从而失败。然后,您应该使用不同的策略“计算”最后插入的值。如果您使用的是不同的DBMS,我建议您使用序列,但对于MySQL,您没有这个选项。因此,您是对的,您将不得不牺牲性能来换取正确性。@a_horse_with_no_name:您知道如果列不是自动递增的,以这种方式锁定方法是否是一种好的做法吗?性能方面的好做法?不,正确性方面的良好实践?可能吧。我怎样才能让
GetLastInserteded
问题正常工作?是通过使列自动递增吗?是的。在插入后,您可以直接运行查询
LAST\u insert\u ID()。因为每个线程都有自己的事务,所以这会起作用。但是,如果设计解决方案是不使用自动增量列,那么锁定写入数据库的方法(同步、重入锁定等)的唯一方法是什么?或者这种情况下是否有任何设计模式?如果设计要求不使用自动增量列,它将无法修复。任何变通办法都会导致微妙的问题。唯一正确的解决方案是使用自动增量-这就是为什么这个功能被发明在第一位!