db4o Tutorial 中文翻译(十一)

本文介绍了db4o数据库在客户端/服务器环境下的应用,包括嵌入式服务器配置、网络通信实现、消息传输机制及一个完整的db4o服务器示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9. 客户端/服务器


Now that we have seen how transactions work in db4o conceptually, we are prepared to tackle concurrently executing transactions.
现在我们已经明白db4o中事务的概念了,本章讲处理并行执行的事务。

现在按照以往熟悉的方法准备数据。
None.gif //  setFirstCar
None.gif
Pilot pilot  =   new  Pilot( " Rubens Barrichello " 99 );
None.gifCar car 
=   new  Car( " BMW " );
None.gifcar.Pilot 
=  pilot;
None.gifdb.Set(car);

None.gif //  setSecondCar
None.gif
Pilot pilot  =   new  Pilot( " Michael Schumacher " 100 );
None.gifCar car 
=   new  Car( " Ferrari " );
None.gifcar.Pilot 
=  pilot;
None.gifdb.Set(car);



9.1. 嵌入式服务器


  • 从API角度看,分布式事务和单一VM上的事务没有什么本质区别。在单机上使用事务,我们需要打开db4o服务器,指示它从0端口运行,从而其他的网络程序不可以占用。

None.gif //  accessLocalServer
None.gif
IObjectServer server  =  Db4oFactory.OpenServer(Util.YapFileName,  0 );
None.gif
try
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    IObjectContainer client 
= server.OpenClient();
InBlock.gif    
// Do something with this client, or open more clients
InBlock.gif
    client.Close();
ExpandedBlockEnd.gif}

None.gif
finally
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    server.Close();
ExpandedBlockEnd.gif}

  • 再次委托打开和关闭数据库的服务器作为运行环境,从而捕捉客户端交互。
None.gif //  queryLocalServer
None.gif
IObjectContainer client  =  server.OpenClient();
None.gifListResult(client.Get(
new  Car( null )));
None.gifclient.Close();


  • 这个事务的级别在db4o里面被成为“read committed”。但是,每个客户端维护它自己的已知对象缓存的引用。为了让其他客户端的变化快速执行,我们需要在服务器端直接引用已知的对象。我们将这个任务代理为一个专门的ListResult()方法的版本。
None.gif public   static   void  ListRefreshedResult(IObjectContainer container, IObjectSet items,  int  depth)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Console.WriteLine(items.Count);
InBlock.gif    
foreach (object item in items)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{    
InBlock.gif        container.Ext().Refresh(item, depth);
InBlock.gif        Console.WriteLine(item);
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif //  demonstrateLocalReadCommitted
None.gif
IObjectContainer client1  = server.OpenClient();
None.gifIObjectContainer client2 
= server.OpenClient();
None.gifPilot pilot 
=   new  Pilot( " David Coulthard " 98 );
None.gifIObjectSet result 
=  client1.Get( new  Car( " BMW " ));
None.gifCar car 
=  (Car)result.Next();
None.gifcar.Pilot 
=  pilot;
None.gifclient1.Set(car);
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Commit();
None.gifListResult(client1.Get(
typeof (Car)));            
None.gifListRefreshedResult(client2, client2.Get(
typeof (Car)),  2 );
None.gifclient1.Close();
None.gifclient2.Close();

会滚也可以这样工作,就像你预料的一样:
None.gif //  demonstrateLocalRollback
None.gif
IObjectContainer client1  =  server.OpenClient();
None.gifIObjectContainer client2 
=  server.OpenClient();
None.gifIObjectSet result 
=  client1.Get( new  Car( " BMW " ));
None.gifCar car 
=  (Car)result.Next();
None.gifcar.Pilot 
=   new  Pilot( " Someone else " 0 );
None.gifclient1.Set(car);
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Rollback();
None.gifclient1.Ext().Refresh(car, 
2 );
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Close();
None.gifclient2.Close();

9.2. 网络


From here it's only a small step towards operating db4o over a TCP/IP network. We just specify a port number greater than zero and set up one or more accounts for our client(s).
到了这里,距离通过TCP/IP协议操作db4o没有多少步骤了。我们需要专门指定一个大于0的端口号码,为客户端设置一个或者更多的帐户。
None.gif //  accessRemoteServer
None.gif
IObjectServer server  =  Db4oFactory.OpenServer(Util.YapFileName, ServerPort);
None.gifserver.GrantAccess(ServerUser, ServerPassword);
None.gif
try
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    IObjectContainer client 
= Db4oFactory.OpenClient("localhost", ServerPort, ServerUser, ServerPassword);
InBlock.gif    
// Do something with this client, or open more clients
InBlock.gif
    client.Close();
ExpandedBlockEnd.gif}

None.gif
finally
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    server.Close();
ExpandedBlockEnd.gif}



.
这个客户端的连接需要提供一个主机、端口、用户名和密码。

None.gif //  queryRemoteServer
None.gif
IObjectContainer client  =  Db4oFactory.OpenClient( " localhost " , port, user, password);
None.gifListResult(client.Get(
new  Car( null )));
None.gifclient.Close();


  • 刚才的所有数据都通过上面的例子检索出来了
None.gif //  demonstrateRemoteReadCommitted
None.gif
IObjectContainer client1  =  Db4oFactory.OpenClient( " localhost " , port, user, password);
None.gifIObjectContainer client2 
=  Db4oFactory.OpenClient( " localhost " , port, user, password);
None.gifPilot pilot 
=   new  Pilot( " Jenson Button " 97 );
None.gifIObjectSet result 
=  client1.Get( new  Car( null ));
None.gifCar car 
=  (Car)result.Next();
None.gifcar.Pilot 
=  pilot;
None.gifclient1.Set(car);
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Commit();
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Close();
None.gifclient2.Close();

None.gif //  demonstrateRemoteRollback
None.gif
IObjectContainer client1  =  Db4oFactory.OpenClient( " localhost " , port, user, password);
None.gifIObjectContainer client2 
=  Db4oFactory.OpenClient( " localhost " , port, user, password);
None.gifIObjectSet result 
=  client1.Get( new  Car( null ));
None.gifCar car 
=  (Car)result.Next();
None.gifcar.Pilot 
=   new  Pilot( " Someone else " 0 );
None.gifclient1.Set(car);
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Rollback();
None.gifclient1.Ext().Refresh(car,
2 );
None.gifListResult(client1.Get(
new  Car( null )));
None.gifListResult(client2.Get(
new  Car( null )));
None.gifclient1.Close();
None.gifclient2.Close();






9.3. 消息传输


  • 有时候客户端需要请求服务器做一些事情,就要发送一个特殊的消息给服务器。服务器需要接受消息、发送消息到涉及的对象。
  • 可以通过SETMESSAGERECIPIENT()方法,找到发送消息的对象。

None.gif public   void  RunServer()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
lock(this)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IObjectServer db4oServer 
= Db4oFactory.OpenServer(FILE, PORT);
InBlock.gif        db4oServer.GrantAccess(USER, PASS);
InBlock.gif        
InBlock.gif        
// Using the messaging functionality to redirect all
InBlock.gif        
// messages to this.processMessage
InBlock.gif
        db4oServer.Ext().Configure().ClientServer().SetMessageRecipient(this);
InBlock.gif        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (! stop)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// wait forever for Notify() from Close()
InBlock.gif
                Monitor.Wait(this);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Console.WriteLine(e.ToString());
ExpandedSubBlockEnd.gif        }

InBlock.gif        db4oServer.Close();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

消息已经接收到了,并且被PROCESSMESSAGE() 方法传递。




db4o允许一个客户端以无格式的类的对象的形式发送一个任意的消息或者信号给服务器。服务器收到后会发回一个收到消息,包含从客户发来的对象。服务器可以任意定义消息的格式。

9.4. 整合--一个简单但是完整的db4oserver


  • 让我们将以上的信息整合,从而写出一个带有专门客户端的简单服务器,客户端可以通知服务器关闭。

  • 首先,服务器和客户端都需要一些共享的设置信息。我们提供一个接口:
None.gif namespace  Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Configuration used for StartServer and StopServer.
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class ServerConfiguration
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the host to be used.
InBlock.gif        
/// If you want to run the client server examples on two computers,
InBlock.gif        
/// enter the computer name of the one that you want to use as server. 
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public const string HOST = "localhost";  
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the database file to be used by the server.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public const string FILE = "formula1.yap";
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the port to be used by the server.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public const int PORT = 4488;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the user name for access control.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public const string USER = "db4o";
InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// the pasword for access control.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public const string PASS = "db4o";
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

创建server:
None.gif 锘縰sing System;
None.gif
using  System.Threading;
None.gif
using  Db4objects.Db4o;
None.gif
using  Db4objects.Db4o.Messaging;
None.gif
namespace  Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// starts a db4o server with the settings from ServerConfiguration.
InBlock.gif    
/// This is a typical setup for a long running server.
InBlock.gif    
/// The Server may be stopped from a remote location by running
InBlock.gif    
/// StopServer. The StartServer instance is used as a MessageRecipient
InBlock.gif    
/// and reacts to receiving an instance of a StopServer object.
InBlock.gif    
/// Note that all user classes need to be present on the server side
InBlock.gif    
/// and that all possible Db4oFactory.Configure() calls to alter the db4o
InBlock.gif    
/// configuration need to be executed on the client and on the server.
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class StartServer : ServerConfiguration, IMessageRecipient
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// setting the value to true denotes that the server should be closed
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        private bool stop = false;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// starts a db4o server using the configuration from
InBlock.gif        
/// ServerConfiguration.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public static void Main(string[] arguments)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
new StartServer().RunServer();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// opens the IObjectServer, and waits forever until Close() is called
InBlock.gif        
/// or a StopServer message is being received.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void RunServer()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
lock(this)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                IObjectServer db4oServer 
= Db4oFactory.OpenServer(FILE, PORT);
InBlock.gif                db4oServer.GrantAccess(USER, PASS);
InBlock.gif                
InBlock.gif                
// Using the messaging functionality to redirect all
InBlock.gif                
// messages to this.processMessage
InBlock.gif
                db4oServer.Ext().Configure().ClientServer().SetMessageRecipient(this);
InBlock.gif                
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (! stop)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
// wait forever for Notify() from Close()
InBlock.gif
                        Monitor.Wait(this);
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Console.WriteLine(e.ToString());
ExpandedSubBlockEnd.gif                }

InBlock.gif                db4oServer.Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// messaging callback
InBlock.gif        
/// see com.db4o.messaging.MessageRecipient#ProcessMessage()
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void ProcessMessage(IObjectContainer con, object message)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (message is StopServer)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// closes this server.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void Close()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
lock(this)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                stop 
= true;
InBlock.gif                Monitor.PulseAll(
this);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif



最后但并不是最不重要的(一点),客户端停止服务器。
None.gif 锘縰sing System;
None.gif
using  Db4objects.Db4o;
None.gif
using  Db4objects.Db4o.Messaging;
None.gif
namespace  Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// stops the db4o Server started with StartServer.
InBlock.gif    
/// This is done by opening a client connection
InBlock.gif    
/// to the server and by sending a StopServer object as
InBlock.gif    
/// a message. StartServer will react in it's
InBlock.gif    
/// processMessage method.
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class StopServer : ServerConfiguration
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// stops a db4o Server started with StartServer.
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <exception cref="Exception" />

InBlock.gif        public static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectContainer IObjectContainer 
= null;
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// connect to the server
InBlock.gif
                IObjectContainer = Db4oFactory.OpenClient(HOST, PORT, USER, PASS);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(e.ToString());
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
if (IObjectContainer != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// get the messageSender for the IObjectContainer
InBlock.gif
                IMessageSender messageSender = IObjectContainer.Ext()
InBlock.gif                    .Configure().ClientServer().GetMessageSender();
InBlock.gif                
// send an instance of a StopServer object
InBlock.gif
                messageSender.Send(new StopServer());
InBlock.gif                
InBlock.gif                
// close the IObjectContainer
InBlock.gif
                IObjectContainer.Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

9.5. 总结



db4o已经是一个家族了。不,当然他不是。有太多db4o没有覆盖的内容:schema 进展,为你的对象定制持久层,书写你自己的查询对象。。等等。更多的文档需要提供,你也可下载获得。
我们希望这个教程已经帮助你开始使用db4o,你该怎么继续呢?

你应该浏览剩下的章节。他们是从我们的网站 http://forums.db4o.com/forums/.选择的话题。



(只是交互版本),实际上,这个教程只是基本的步骤而已,试着在章节间来回,运行代码片段,你便可以完全掌握db4o。有时候,你有了困难,甚至发生异常,但是随时可以在命令窗口重置数据库。


这些例子都有源代码。所以你可以自由的实验。

如果遇到困难,看看FAQ有没有作用。 在我们的 web site浏览信息, 看看你的问题是否被提交到 Jira ,或者访问我们的论坛: http://forums.db4o.com/forums/.

转载于:https://www.cnblogs.com/xxpyeippx/archive/2007/05/06/737302.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值