gpt4 book ai didi

java - 使用 Hibernate、Postgres 和 Guice Provider 时“事务中空闲”

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

当我执行时:

select * from pg_stat_activity where state ~ 'idle in transact'

我得到的行数不适当,状态为“事务中空闲”。他们中的一些人闲置了几天。其中大部分是从一个服务类(Hibernate 5.1.0.Final、Guice 4.1.0)执行的相同的简单select 查询:

public class FirebaseServiceImpl implements FirebaseService {

@Inject
private Provider<FirebaseKeyDAO> firebaseKeyDAO;

@Override
public void sendNotification(User recipient) {

List<FirebaseKey> firebaseKeys = firebaseKeyDAO.get().findByUserId(recipient.getId());

final ExecutorService notificationsPool = Executors.newFixedThreadPool(3);

for (FirebaseKey firebaseKey : firebaseKeys)
notificationsPool.execute(new Runnable() {

@Override
public void run() {
sendNotification(new FirebaseNotification(firebaseKey.getFirebaseKey(), "example");
}
});

notificationsPool.shutdown();
}
}

DAO 方法:

@Override
@SuppressWarnings("unchecked")
public List<FirebaseKey> findByUserId(Long userId) {
Criteria criteria = getSession().createCriteria(type);
criteria.add(Restrictions.eq("userId", userId));
return criteria.list();
}

为什么会这样?如何避免这种情况?

更新

当我在单独的线程中使用 Guice Provider exampleDAO.get() 时,交易没有提交:

@Inject
Provider<ExampleDAO> exampleDAO;

最佳答案

当您使用 pgbouncer 或其他使用 pool_mode = transaction 的 pooler/session 管理器时,通常会发生这种情况。例如,当客户打开一个事务并持有它时,既不提交也不回滚。检查您是否在查询列中看到 DISCARD ALL - 如果是这种情况,because pooler 必须丢弃共享的 session 计划、序列、解除分配语句等,以避免在池中混合不同 session 的那些。

另一方面,任何“正常”交易都会产生相同的idle in transaction,例如:

2>select now(),pg_backend_pid();
now | pg_backend_pid
----------------------------------+----------------
2017-05-05 16:53:01.867444+05:30 | 26500
(1 row)

如果我们检查它的状态,我们会看到正统的 idle:

t=# select query,state from pg_stat_activity where pid = 26500;
query | state
--------------------------------+-------
select now(),pg_backend_pid(); | idle
(1 row)

现在我们在 session 2> 上开始交易:2>开始;开始

2>select now(),pg_backend_pid();
now | pg_backend_pid
----------------------------------+----------------
2017-05-05 16:54:15.856306+05:30 | 26500
(1 row)

并检查pg_stat_statements 获得:

t=# select query,state from pg_stat_activity where pid = 26500;
query | state
--------------------------------+---------------------
select now(),pg_backend_pid(); | idle in transaction
(1 row)

它将保持这种状态直到语句超时或事务结束:

2>end;
COMMIT
t=# select query,state from pg_stat_activity where pid = 26500;
query | state
-------+-------
end; | idle
(1 row)

所以拥有它是很常见的。如果你想避免连接的 session ,你必须断开客户端。但是 postgres 中的连接是昂贵的,所以通常人们会尝试使用池重用现有的连接,所以这样的状态出现在 pg_stat_activity

关于java - 使用 Hibernate、Postgres 和 Guice Provider 时“事务中空闲”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43803627/

25 4 0
文章推荐: java - 最好在查询中使用 DISTINCT 进行过滤,或者在解析所述查询的结果时使用 java 的集合
文章推荐: ios - 在 iOS 上无法从 Pebble 接收 AppMessage
文章推荐: iOS Guided Access 模式破坏了 HTML