ORACLE数据库比用JAVA实现邮件自动告警功能的优势
大家用过监控系统的可能知道,被监控的项目发生错误,要第一时间扑捉到错误并发邮件出来告知大家,最好能够做到同步,因为时间就是金钱,及时发现,及时处理,如果有损失也可以降到最低,对吧。那么问题来了,怎样能做到同步,即发生错误,就邮件告警呢,有朋友会用java来实现,对,java也可以实现,java实现要用定时任务吧,一秒中执行一次,去连接数据库,这样就会存在性能的问题,不管有没有错误,java的定时任务都在执行,那我们能不能做到当发生错误时,才执行我们发邮件的功能呢,当然,是可以的。
Oracle中实现自动邮件告警功能需要了解数据库的触发器、创建java类、创建oracle方法、调用oracle方法。当然,所有的操作都在PL/SQL完成的,下面就是我们的实现步骤。
1.创建JAVA发邮件的类。
create or replace and compile java source named orcjavademo as
import java.sql.*;
import java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class OrcJavaDemo
{
public static String entry(String name)
{
boolean flag = true;
//建立邮件会话
Properties pro ();= new Properties
pro.put("mail.smtp.host","邮件服务器的IP");//存储发送邮件的服务器
pro.put("mail.smtp.auth","true"); //通过服务器验证
Session s =Session.getInstance(pro); //根据属性新建一个邮件会话
//s.setDebug(true);
//由邮件会话新建一个消息对象
MimeMessage message = new MimeMessage(s);
//设置邮件
InternetAddress fromAddr = null;
// InternetAddress toAddr = null;
String[] arrayToAddr={"收件人邮箱地址1","收件人邮箱地址2","收件人邮箱地址3"};
InternetAddress[] toAddr =new InternetAddress[arrayToAddr.length];
try
{
for (int i = 0; i
toAddr[i]=new InternetAddress(arrayToAddr[i]);
}
fromAddr = new InternetAddress("发件人邮箱地址"); //邮件发送地址
message.setFrom(fromAddr); //设置发送地址
message.setRecipients(Message.RecipientType.TO, toAddr);
message.setSubject(""); //设置邮件标题
//发送文本
message.setText("");//邮件正文
message.setSentDate(new Date()); //设置邮件日期
message.saveChanges(); //保存邮件更改信息
Transport transport = s.getTransport("smtp");
transport.connect("邮件服务器IP", "发件人用户名", "发件人密码"); //服务器地址,邮箱账号,邮箱密码
transport.sendMessage(message, message.getAllRecipients()); //发送邮件
transport.close();//关闭
}
catch (Exception e)
{
System.out.println(e);
// e.printStackTrace();
flag = false;//发送失败
}
return flag+"=OK";
}
}
执行该部分完成后,我们还需要检查java类在oracle中是否编译成功。把SQL窗口切换到命令行窗口,输入show errors java source orcjavademo,执行完后,提示成功,即编译通过。
2.创建Oracle方法,用于调用java类。
CREATE OR REPLACE FUNCTION testFun(transtime varchar2) return varchar2
AS LANGUAGE JAVA NAME 'OrcJavaDemo.entry(java.lang.String) return java.lang.String';
执行完该部分后,我们可以手动调用oracle方法,测试下我们邮件告警功能
begin
dbms_output.put_line(testFun('hello World'));
end;
执行完该部分,我们在输出窗口会发现两个问题:
第一个问题: java的代码中的输出语句怎么没打印出来,这个时候需要我们执行 call dbms_java.set_output(2000);
第二个问题: 输出窗口报了一个错误:
java.security.AccessControlException: the Permission (java.net.SocketPermission
smtp.
因为当前Oracle用户没有操作java代码权限,只要将javasyspri角色赋予当前用户就行了。grant javasyspri to **用户
如果手动调用没有问题,并邮件发送成功,我们就完成最后一步了。
3.创建触发器,自动完成调用。
create or replace trigger 触发器名称
after insert on 数据库表名
For each row
declare
name varchar2(50);
Begin
name:=:new.name;
dbms_output.put_line(testFun(name));
Dbms_output.put_line('触发器已被执行');
End;
4.进行测试。当我们用insert语句插入到数据库时,将会满足触发器条件,进行自动调用oracle方法,完成自动邮件告警功能。
后期还会完善,将java代码的邮箱部分保存到配置文件中,还会做根据参数不同,收件人也不同,完成邮箱权限的功能。敬请期待,谢谢大家。