什么是逻辑会话(Logical Sessions)
概述
在dds中,服务端会话(server sessions)或者逻辑会话(logical sessions)是一种机制,用于在服务端维护和管理客户端的操作状态。应用程序使用客户端会话与服务端会话进行交互。
会话的生命周期
- 会话的创建
- 会话的显式创建
会话在客户端请求时由服务端创建。会话通常由驱动程序通过API创建。例如,使用mongo shell创建session:
// Start a session. session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
创建的会话将在服务端维护一个独特的会话ID,用于识别和管理会话。
session { "id" : UUID("1c6480a3-8e8d-4726-9f1b-6bf2f6b2b606") }
- 会话的隐式创建
隐式会话是指在执行某些操作时,驱动程序自动创建会话而无需显式地调用startSession方法。隐式会话主要用于简化开发者的代码,使操作更加便捷。当客户执行数据库操作而没有显式地提供会话参数时,驱动程序会自动创建一个会话。例如,在插入文档或查询数据时,驱动程序会在后台创建一个隐式会话,并在操作完成后自动结束会话。
服务端可以缓存的最大会话数默认为1000000,当会话数大于该值时,将无法显式或者隐式创建会话。
会话达到上限时的行为
- 拒绝新的会话:如果会话资源达到上限,DDS将无法创建新的会话。这意味着新的操作请求将会被拒绝或阻塞,直到现有的会话释放资源。
- 资源争用:大量的会话可能会导致资源争用,例如内存和CPU利用率增加。这可能会影响数据库的性能和响应时间。
- 事务失败:如果在会话达到上限时尝试启动新事务,可能会导致事务失败。客户端会收到错误消息,指示会话资源已耗尽。
- 会话的使用
会话在使用过程中可以进行多种数据库操作,包括读写操作和事务操作。所有在会话上下文中的操作都会绑定到该会话。例如:
coll1 = session.getDatabase("mydb1").foo; coll2 = session.getDatabase("mydb2").bar; coll1.insertOne( { abc: 1 } ); coll2.insertOne( { xyz: 999 } )。
- 会话的终止
会话可以显式终止,也可以在超时后自动终止。显式终止通过调用endSession方法:
session.endSession();
服务器会自动清理终止会话所占用的资源。
- 会话的显式创建
- 会话的管理
- 事务管理
会话是事务管理的核心。在事务开始时,服务器会在会话上下文中记录事务操作,确保这些操作要么全部提交,要么全部回滚。例如:
db.getSiblingDB("mydb1").foo.insertOne( {abc: 0}, { writeConcern: { w: "majority", wtimeout: 2000 } } ) db.getSiblingDB("mydb2").bar.insertOne( {xyz: 0}, { writeConcern: { w: "majority", wtimeout: 2000 } } ) // Start a session. session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); coll1 = session.getDatabase("mydb1").foo; coll2 = session.getDatabase("mydb2").bar; // Start a transaction session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } ); // Operations inside the transaction try { coll1.insertOne( { abc: 1 } ); coll2.insertOne( { xyz: 999 } ); } catch (error) { // Abort transaction on error session.abortTransaction(); throw error; } // Commit the transaction using write concern set at transaction start session.commitTransaction(); session.endSession();
- 会话超时
- 事务管理
逻辑会话的实现细节
使用最佳实践
- 指定w=majority:建议客户在连接DDS实例时指定w=majority,防止主备时延大导致隐式会话累积残留,此外,如果没有以w=majority写入数据,则发生主备倒换时,未同步到备机的数据有丢失风险。
- 显式结束会话:尽量在操作完成后显式调用endSession,以释放资源。
- 事务内操作尽量少:在事务内执行的操作应尽量少且简洁,以减少锁定和资源占用。